Johny Mattsson 526d21dab4 Major cleanup - c_whatever is finally history. (#2838)
The PR removed the bulk of non-newlib headers from the NodeMCU source base.  
app/libc has now been cut down to the bare minimum overrides to shadow the 
corresponding functions in the SDK's libc. The old c_xyz.h headerfiles have been 
nuked in favour of the standard <xyz.h> headers, with a few exceptions over in 
sdk-overrides. Again, shipping a libc.a without headers is a terrible thing to do. We're 
still living on a prayer that libc was configured the same was as a default-configured
xtensa gcc toolchain assumes it is. That part I cannot do anything about, unfortunately, 
but it's no worse than it has been before.

This enables our source files to compile successfully using the standard header files, 
and use the typical malloc()/calloc()/realloc()/free(), the strwhatever()s and 
memwhatever()s. These end up, through macro and linker magic, mapped to the 
appropriate SDK or ROM functions.
2019-07-22 00:58:21 +03:00

599 lines
23 KiB
C

//***************************************************************************
// Si7021 module for ESP8266 with nodeMCU
// fetchbot @github
// MIT license, http://opensource.org/licenses/MIT
//***************************************************************************
#include "module.h"
#include "lauxlib.h"
#include "platform.h"
#include "osapi.h"
#include <stdlib.h>
//***************************************************************************
// CHIP
//***************************************************************************
#define ADS1115_ADS1015 ( 15)
#define ADS1115_ADS1115 (115)
//***************************************************************************
// I2C ADDRESS DEFINITON
//***************************************************************************
#define ADS1115_I2C_ADDR_GND (0x48)
#define ADS1115_I2C_ADDR_VDD (0x49)
#define ADS1115_I2C_ADDR_SDA (0x4A)
#define ADS1115_I2C_ADDR_SCL (0x4B)
#define IS_I2C_ADDR_VALID(addr) (((addr) & 0xFC) == 0x48)
//***************************************************************************
// POINTER REGISTER
//***************************************************************************
#define ADS1115_POINTER_MASK (0x03)
#define ADS1115_POINTER_CONVERSION (0x00)
#define ADS1115_POINTER_CONFIG (0x01)
#define ADS1115_POINTER_THRESH_LOW (0x02)
#define ADS1115_POINTER_THRESH_HI (0x03)
//***************************************************************************
// CONFIG REGISTER
//***************************************************************************
#define ADS1115_OS_MASK (0x8000)
#define ADS1115_OS_NON (0x0000)
#define ADS1115_OS_SINGLE (0x8000) // Write: Set to start a single-conversion
#define ADS1115_OS_BUSY (0x0000) // Read: Bit = 0 when conversion is in progress
#define ADS1115_OS_NOTBUSY (0x8000) // Read: Bit = 1 when device is not performing a conversion
#define ADS1115_MUX_MASK (0x7000)
#define ADS1115_MUX_DIFF_0_1 (0x0000) // Differential P = AIN0, N = AIN1 (default)
#define ADS1115_MUX_DIFF_0_3 (0x1000) // Differential P = AIN0, N = AIN3
#define ADS1115_MUX_DIFF_1_3 (0x2000) // Differential P = AIN1, N = AIN3
#define ADS1115_MUX_DIFF_2_3 (0x3000) // Differential P = AIN2, N = AIN3
#define ADS1115_MUX_SINGLE_0 (0x4000) // Single-ended AIN0
#define ADS1115_MUX_SINGLE_1 (0x5000) // Single-ended AIN1
#define ADS1115_MUX_SINGLE_2 (0x6000) // Single-ended AIN2
#define ADS1115_MUX_SINGLE_3 (0x7000) // Single-ended AIN3
#define IS_CHANNEL_VALID(channel) (((channel) & 0x8FFF) == 0)
#define ADS1115_PGA_MASK (0x0E00)
#define ADS1115_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3
#define ADS1115_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1
#define ADS1115_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default)
#define ADS1115_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4
#define ADS1115_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8
#define ADS1115_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16
#define ADS1115_MODE_MASK (0x0100)
#define ADS1115_MODE_CONTIN (0x0000) // Continuous conversion mode
#define ADS1115_MODE_SINGLE (0x0100) // Power-down single-shot mode (default)
#define ADS1115_DR_MASK (0x00E0)
#define ADS1115_DR_8SPS ( 8)
#define ADS1115_DR_16SPS ( 16)
#define ADS1115_DR_32SPS ( 32)
#define ADS1115_DR_64SPS ( 64)
#define ADS1115_DR_128SPS ( 128)
#define ADS1115_DR_250SPS ( 250)
#define ADS1115_DR_475SPS ( 475)
#define ADS1115_DR_490SPS ( 490)
#define ADS1115_DR_860SPS ( 860)
#define ADS1115_DR_920SPS ( 920)
#define ADS1115_DR_1600SPS (1600)
#define ADS1115_DR_2400SPS (2400)
#define ADS1115_DR_3300SPS (3300)
#define ADS1115_CMODE_MASK (0x0010)
#define ADS1115_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default)
#define ADS1115_CMODE_WINDOW (0x0010) // Window comparator
#define ADS1115_CPOL_MASK (0x0008)
#define ADS1115_CPOL_ACTVLOW (0x0000) // ALERT/RDY pin is low when active (default)
#define ADS1115_CPOL_ACTVHI (0x0008) // ALERT/RDY pin is high when active
#define ADS1115_CLAT_MASK (0x0004) // Determines if ALERT/RDY pin latches once asserted
#define ADS1115_CLAT_NONLAT (0x0000) // Non-latching comparator (default)
#define ADS1115_CLAT_LATCH (0x0004) // Latching comparator
#define ADS1115_CQUE_MASK (0x0003)
#define ADS1115_CQUE_1CONV (0x0000) // Assert ALERT/RDY after one conversions
#define ADS1115_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions
#define ADS1115_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions
#define ADS1115_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default)
#define ADS1115_DEFAULT_CONFIG_REG (0x8583) // Config register value after reset
// #define ADS1115_INCLUDE_TEST_FUNCTION
//***************************************************************************
static const uint8_t ads1115_i2c_id = 0;
static const uint8_t general_i2c_addr = 0x00;
static const uint8_t ads1115_i2c_reset = 0x06;
static const char metatable_name[] = "ads1115.device";
static const char unexpected_value[] = "unexpected value";
typedef struct {
uint8_t i2c_addr;
uint8_t chip_id;
uint16_t gain;
uint16_t samples_value; // sample per second
uint16_t samples; // register value
uint16_t comp;
uint16_t mode;
uint16_t threshold_low;
uint16_t threshold_hi;
uint16_t config;
int timer_ref;
os_timer_t timer;
} ads_ctrl_ud_t;
static int ads1115_lua_readoutdone(void * param);
static int ads1115_lua_register(lua_State *L, uint8_t chip_id);
static uint8_t write_reg(uint8_t ads_addr, uint8_t reg, uint16_t config) {
platform_i2c_send_start(ads1115_i2c_id);
platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(ads1115_i2c_id, reg);
platform_i2c_send_byte(ads1115_i2c_id, (uint8_t)(config >> 8));
platform_i2c_send_byte(ads1115_i2c_id, (uint8_t)(config & 0xFF));
platform_i2c_send_stop(ads1115_i2c_id);
}
static uint16_t read_reg(uint8_t ads_addr, uint8_t reg) {
platform_i2c_send_start(ads1115_i2c_id);
platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(ads1115_i2c_id, reg);
platform_i2c_send_stop(ads1115_i2c_id);
platform_i2c_send_start(ads1115_i2c_id);
platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
uint16_t buf = (platform_i2c_recv_byte(ads1115_i2c_id, 1) << 8);
buf += platform_i2c_recv_byte(ads1115_i2c_id, 0);
platform_i2c_send_stop(ads1115_i2c_id);
return buf;
}
// convert ADC value to voltage corresponding to PGA settings
// returned voltage is in milivolts
static double get_mvolt(uint16_t gain, uint16_t value) {
double volt = 0;
switch (gain) {
case (ADS1115_PGA_6_144V):
volt = (int16_t)value * 0.1875;
break;
case (ADS1115_PGA_4_096V):
volt = (int16_t)value * 0.125;
break;
case (ADS1115_PGA_2_048V):
volt = (int16_t)value * 0.0625;
break;
case (ADS1115_PGA_1_024V):
volt = (int16_t)value * 0.03125;
break;
case (ADS1115_PGA_0_512V):
volt = (int16_t)value * 0.015625;
break;
case (ADS1115_PGA_0_256V):
volt = (int16_t)value * 0.0078125;
break;
}
return volt;
}
// validates and convert threshold in volt to ADC value corresponding to PGA settings
// returns true if valid
static uint8_t get_value(uint16_t gain, uint16_t channel, int16_t *volt) {
switch (gain) {
case (ADS1115_PGA_6_144V):
if ((*volt >= 6144) || (*volt < -6144) || ((*volt < 0) && (channel >> 14))) return 0;
*volt = *volt / 0.1875;
break;
case (ADS1115_PGA_4_096V):
if ((*volt >= 4096) || (*volt < -4096) || ((*volt < 0) && (channel >> 14))) return 0;
*volt = *volt / 0.125;
break;
case (ADS1115_PGA_2_048V):
if ((*volt >= 2048) || (*volt < -2048) || ((*volt < 0) && (channel >> 14))) return 0;
*volt = *volt / 0.0625;
break;
case (ADS1115_PGA_1_024V):
if ((*volt >= 1024) || (*volt < -1024) || ((*volt < 0) && (channel >> 14))) return 0;
*volt = *volt / 0.03125;
break;
case (ADS1115_PGA_0_512V):
if ((*volt >= 512) || (*volt < -512) || ((*volt < 0) && (channel >> 14))) return 0;
*volt = *volt / 0.015625;
break;
case (ADS1115_PGA_0_256V):
if ((*volt >= 256) || (*volt < -256) || ((*volt < 0) && (channel >> 14))) return 0;
*volt = *volt / 0.0078125;
break;
}
return 1;
}
// Reset of all devices
// Lua: ads1115.reset()
static int ads1115_lua_reset(lua_State *L) {
platform_i2c_send_start(ads1115_i2c_id);
platform_i2c_send_address(ads1115_i2c_id, general_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(ads1115_i2c_id, ads1115_i2c_reset);
platform_i2c_send_stop(ads1115_i2c_id);
return 0;
}
// Register an ADS device
// Lua: ads1115.ADS1115(I2C_ID, ADDRESS)
static int ads1115_lua_register_1115(lua_State *L) {
return ads1115_lua_register(L, ADS1115_ADS1115);
}
static int ads1115_lua_register_1015(lua_State *L) {
return ads1115_lua_register(L, ADS1115_ADS1015);
}
static int ads1115_lua_register(lua_State *L, uint8_t chip_id) {
uint8_t i2c_id = luaL_checkinteger(L, 1);
luaL_argcheck(L, 0 == i2c_id, 1, "i2c_id must be 0");
uint8_t i2c_addr = luaL_checkinteger(L, 2);
luaL_argcheck(L, IS_I2C_ADDR_VALID(i2c_addr), 2, unexpected_value);
uint16_t config_read = read_reg(i2c_addr, ADS1115_POINTER_CONFIG);
if (config_read == 0xFFFF) {
return luaL_error(L, "found no device");
}
if (config_read != ADS1115_DEFAULT_CONFIG_REG) {
return luaL_error(L, "unexpected config value (%p) please reset device before calling this function", config_read);
}
ads_ctrl_ud_t *ads_ctrl = (ads_ctrl_ud_t *)lua_newuserdata(L, sizeof(ads_ctrl_ud_t));
if (NULL == ads_ctrl) {
return luaL_error(L, "ads1115 malloc: out of memory");
}
luaL_getmetatable(L, metatable_name);
lua_setmetatable(L, -2);
ads_ctrl->chip_id = chip_id;
ads_ctrl->i2c_addr = i2c_addr;
ads_ctrl->gain = ADS1115_PGA_6_144V;
ads_ctrl->samples = ADS1115_DR_128SPS;
ads_ctrl->samples_value = chip_id == ADS1115_ADS1115 ? 128 : 1600;
ads_ctrl->comp = ADS1115_CQUE_NONE;
ads_ctrl->mode = ADS1115_MODE_SINGLE;
ads_ctrl->threshold_low = 0x8000;
ads_ctrl->threshold_hi = 0x7FFF;
ads_ctrl->config = ADS1115_DEFAULT_CONFIG_REG;
ads_ctrl->timer_ref = LUA_NOREF;
return 1;
}
// Change the ADC device settings
// Lua: ads1115.device:settings(GAIN,SAMPLES,CHANNEL,MODE[,CONVERSION_RDY][,COMPARATOR,THRESHOLD_LOW,THRESHOLD_HI[,COMP_MODE])
static int ads1115_lua_setting(lua_State *L) {
int argc = lua_gettop(L);
if (argc != 5 && argc != 6 && argc != 8 && argc != 9) { // user data counts
luaL_error(L, "invalid number of arguments to 'setting'");
}
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
// gain
uint16_t gain = luaL_checkinteger(L, 2);
luaL_argcheck(L, (gain == ADS1115_PGA_6_144V) || (gain == ADS1115_PGA_4_096V) || (gain == ADS1115_PGA_2_048V) ||
(gain == ADS1115_PGA_1_024V) || (gain == ADS1115_PGA_0_512V) || (gain == ADS1115_PGA_0_256V),
2, unexpected_value);
ads_ctrl->gain = gain;
// samples
uint16_t samples_value = luaL_checkinteger(L, 3);
uint16_t samples = 0;
if (ads_ctrl->chip_id == ADS1115_ADS1115) {
switch(samples_value) {
case ADS1115_DR_8SPS:
samples = 0;
break;
case ADS1115_DR_16SPS:
samples = 0x20;
break;
case ADS1115_DR_32SPS:
samples = 0x40;
break;
case ADS1115_DR_64SPS:
samples = 0x60;
break;
case ADS1115_DR_128SPS: // default
samples = 0x80;
break;
case ADS1115_DR_250SPS:
samples = 0xA0;
break;
case ADS1115_DR_475SPS:
samples = 0xC0;
break;
case ADS1115_DR_860SPS:
samples = 0xE0;
break;
default:
luaL_argerror(L, 3, unexpected_value);
}
} else { // ADS1115_ADS1015
switch(samples_value) {
case ADS1115_DR_128SPS:
samples = 0;
break;
case ADS1115_DR_250SPS:
samples = 0x20;
break;
case ADS1115_DR_490SPS:
samples = 0x40;
break;
case ADS1115_DR_920SPS:
samples = 0x60;
break;
case ADS1115_DR_1600SPS: // default
samples = 0x80;
break;
case ADS1115_DR_2400SPS:
samples = 0xA0;
break;
case ADS1115_DR_3300SPS:
samples = 0xC0;
break;
default:
luaL_argerror(L, 3, unexpected_value);
}
}
ads_ctrl->samples = samples;
ads_ctrl->samples_value = samples_value;
// channel
uint16_t channel = luaL_checkinteger(L, 4);
luaL_argcheck(L, IS_CHANNEL_VALID(channel), 4, unexpected_value);
// mode
uint16_t mode = luaL_checkinteger(L, 5);
luaL_argcheck(L, (mode == ADS1115_MODE_SINGLE) || (mode == ADS1115_MODE_CONTIN), 5, unexpected_value);
ads_ctrl->mode = mode;
uint16_t os = mode == ADS1115_MODE_SINGLE ? ADS1115_OS_SINGLE : ADS1115_OS_NON;
uint16_t comp = ADS1115_CQUE_NONE;
// Parse optional parameters
if (argc > 5) {
// comparator or conversion count
comp = luaL_checkinteger(L, 6);
luaL_argcheck(L, (comp == ADS1115_CQUE_1CONV) || (comp == ADS1115_CQUE_2CONV) || (comp == ADS1115_CQUE_4CONV),
6, unexpected_value);
uint16_t threshold_low = 0x7FFF;
uint16_t threshold_hi = 0x8000;
if (argc > 6) {
// comparator thresholds
threshold_low = luaL_checkinteger(L, 7);
threshold_hi = luaL_checkinteger(L, 8);
luaL_argcheck(L, (int16_t)threshold_low <= (int16_t)threshold_hi, 7, "threshold_low > threshold_hi");
luaL_argcheck(L, get_value(gain, channel, &threshold_low), 7, unexpected_value);
luaL_argcheck(L, get_value(gain, channel, &threshold_hi), 8, unexpected_value);
}
ads_ctrl->threshold_low = threshold_low;
ads_ctrl->threshold_hi = threshold_hi;
NODE_DBG("ads1115 low: %04x\n", threshold_low);
NODE_DBG("ads1115 hi : %04x\n", threshold_hi);
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_THRESH_LOW, threshold_low);
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_THRESH_HI, threshold_hi);
}
ads_ctrl->comp = comp;
uint16_t comparator_mode = ADS1115_CMODE_TRAD;
if (argc == 9) {
comparator_mode = luaL_checkinteger(L, 9);
luaL_argcheck(L, (comparator_mode == ADS1115_CMODE_WINDOW) || (comparator_mode == ADS1115_CMODE_TRAD),
9, unexpected_value);
}
uint16_t config = (os | channel | gain | mode | samples | comparator_mode | ADS1115_CPOL_ACTVLOW | ADS1115_CLAT_NONLAT | comp);
ads_ctrl->config = config;
NODE_DBG("ads1115 config: %04x\n", ads_ctrl->config);
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, config);
return 0;
}
// Read the conversion register from the ADC device
// Lua: ads1115.device:startread(function(volt, voltdec, adc, sign) print(volt,voltdec,adc,sign) end)
static int ads1115_lua_startread(lua_State *L) {
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
if (((ads_ctrl->comp == ADS1115_CQUE_1CONV) ||
(ads_ctrl->comp == ADS1115_CQUE_2CONV) ||
(ads_ctrl->comp == ADS1115_CQUE_4CONV)) &&
(ads_ctrl->threshold_low == 0x7FFF) &&
(ads_ctrl->threshold_hi == 0x8000)) {
// conversion ready mode
if (ads_ctrl->mode == ADS1115_MODE_SINGLE) {
NODE_DBG("ads1115 trigger config: %04x", ads_ctrl->config);
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, ads_ctrl->config);
}
return 0;
}
luaL_argcheck(L, (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION), 2, "Must be function");
lua_pushvalue(L, 2);
ads_ctrl->timer_ref = luaL_ref(L, LUA_REGISTRYINDEX);
if (ads_ctrl->mode == ADS1115_MODE_SINGLE) {
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, ads_ctrl->config);
}
// Start a timer to wait until ADC conversion is done
os_timer_disarm(&ads_ctrl->timer);
os_timer_setfn(&ads_ctrl->timer, (os_timer_func_t *)ads1115_lua_readoutdone, (void *)ads_ctrl);
int msec = 1; // ADS1115_DR_1600SPS, ADS1115_DR_2400SPS, ADS1115_DR_3300SPS
switch (ads_ctrl->samples_value) {
case ADS1115_DR_8SPS:
msec = 150;
break;
case ADS1115_DR_16SPS:
msec = 75;
break;
case ADS1115_DR_32SPS:
msec = 35;
break;
case ADS1115_DR_64SPS:
msec = 20;
break;
case ADS1115_DR_128SPS:
msec = 10;
break;
case ADS1115_DR_250SPS:
msec = 5;
break;
case ADS1115_DR_475SPS:
case ADS1115_DR_490SPS:
msec = 3;
break;
case ADS1115_DR_860SPS:
case ADS1115_DR_920SPS:
msec = 2;
}
os_timer_arm(&ads_ctrl->timer, msec, 0);
return 0;
}
static void read_common(ads_ctrl_ud_t * ads_ctrl, uint16_t raw, lua_State *L) {
double mvolt = get_mvolt(ads_ctrl->gain, raw);
#ifdef LUA_NUMBER_INTEGRAL
int sign;
if (mvolt == 0) {
sign = 0;
} else if (mvolt > 0) {
sign = 1;
} else {
sign = -1;
}
int uvolt;
if (sign >= 0) {
uvolt = (int)((mvolt - (int)mvolt) * 1000 + 0.5);
} else {
uvolt = -(int)((mvolt - (int)mvolt) * 1000 - 0.5);
mvolt = -mvolt;
}
lua_pushnumber(L, mvolt);
lua_pushinteger(L, uvolt);
lua_pushinteger(L, raw);
lua_pushinteger(L, sign);
#else
lua_pushnumber(L, mvolt);
lua_pushnil(L);
lua_pushinteger(L, raw);
lua_pushnil(L);
#endif
}
// adc conversion timer callback
static int ads1115_lua_readoutdone(void * param) {
ads_ctrl_ud_t * ads_ctrl = (ads_ctrl_ud_t *)param;
uint16_t raw = read_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONVERSION);
lua_State *L = lua_getstate();
os_timer_disarm(&ads_ctrl->timer);
lua_rawgeti(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
ads_ctrl->timer_ref = LUA_NOREF;
read_common(ads_ctrl, raw, L);
lua_call(L, 4, 0);
}
// Read the conversion register from the ADC device
// Lua: volt,voltdec,adc,sign = ads1115.device:read()
static int ads1115_lua_read(lua_State *L) {
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
uint16_t raw = read_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONVERSION);
read_common(ads_ctrl, raw, L);
return 4;
}
#ifdef ADS1115_INCLUDE_TEST_FUNCTION
// this function simulates conversion using raw value provided as argument
// Lua: volt,volt_dec,adc,sign = ads1115.test_volt_conversion(-1)
static int test_volt_conversion(lua_State *L) {
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
uint16_t raw = luaL_checkinteger(L, 2);
read_common(ads_ctrl, raw, L);
return 4;
}
#endif
static int ads1115_lua_delete(lua_State *L) {
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
if (ads_ctrl->timer_ref != LUA_NOREF) {
os_timer_disarm(&ads_ctrl->timer);
luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
}
return 0;
}
LROT_BEGIN(ads1115)
LROT_FUNCENTRY( ads1115, ads1115_lua_register_1115 )
LROT_FUNCENTRY( ads1015, ads1115_lua_register_1015 )
LROT_FUNCENTRY( reset, ads1115_lua_reset )
LROT_NUMENTRY( ADDR_GND, ADS1115_I2C_ADDR_GND )
LROT_NUMENTRY( ADDR_VDD, ADS1115_I2C_ADDR_VDD )
LROT_NUMENTRY( ADDR_SDA, ADS1115_I2C_ADDR_SDA )
LROT_NUMENTRY( ADDR_SCL, ADS1115_I2C_ADDR_SCL )
LROT_NUMENTRY( SINGLE_SHOT, ADS1115_MODE_SINGLE )
LROT_NUMENTRY( CONTINUOUS, ADS1115_MODE_CONTIN )
LROT_NUMENTRY( DIFF_0_1, ADS1115_MUX_DIFF_0_1 )
LROT_NUMENTRY( DIFF_0_3, ADS1115_MUX_DIFF_0_3 )
LROT_NUMENTRY( DIFF_1_3, ADS1115_MUX_DIFF_1_3 )
LROT_NUMENTRY( DIFF_2_3, ADS1115_MUX_DIFF_2_3 )
LROT_NUMENTRY( SINGLE_0, ADS1115_MUX_SINGLE_0 )
LROT_NUMENTRY( SINGLE_1, ADS1115_MUX_SINGLE_1 )
LROT_NUMENTRY( SINGLE_2, ADS1115_MUX_SINGLE_2 )
LROT_NUMENTRY( SINGLE_3, ADS1115_MUX_SINGLE_3 )
LROT_NUMENTRY( GAIN_6_144V, ADS1115_PGA_6_144V )
LROT_NUMENTRY( GAIN_4_096V, ADS1115_PGA_4_096V )
LROT_NUMENTRY( GAIN_2_048V, ADS1115_PGA_2_048V )
LROT_NUMENTRY( GAIN_1_024V, ADS1115_PGA_1_024V )
LROT_NUMENTRY( GAIN_0_512V, ADS1115_PGA_0_512V )
LROT_NUMENTRY( GAIN_0_256V, ADS1115_PGA_0_256V )
LROT_NUMENTRY( DR_8SPS, ADS1115_DR_8SPS )
LROT_NUMENTRY( DR_16SPS, ADS1115_DR_16SPS )
LROT_NUMENTRY( DR_32SPS, ADS1115_DR_32SPS )
LROT_NUMENTRY( DR_64SPS, ADS1115_DR_64SPS )
LROT_NUMENTRY( DR_128SPS, ADS1115_DR_128SPS )
LROT_NUMENTRY( DR_250SPS, ADS1115_DR_250SPS )
LROT_NUMENTRY( DR_475SPS, ADS1115_DR_475SPS )
LROT_NUMENTRY( DR_490SPS, ADS1115_DR_490SPS )
LROT_NUMENTRY( DR_860SPS, ADS1115_DR_860SPS )
LROT_NUMENTRY( DR_920SPS, ADS1115_DR_920SPS )
LROT_NUMENTRY( DR_1600SPS, ADS1115_DR_1600SPS )
LROT_NUMENTRY( DR_2400SPS, ADS1115_DR_2400SPS )
LROT_NUMENTRY( DR_3300SPS, ADS1115_DR_3300SPS )
LROT_NUMENTRY( CONV_RDY_1, ADS1115_CQUE_1CONV )
LROT_NUMENTRY( CONV_RDY_2, ADS1115_CQUE_2CONV )
LROT_NUMENTRY( CONV_RDY_4, ADS1115_CQUE_4CONV )
LROT_NUMENTRY( COMP_1CONV, ADS1115_CQUE_1CONV )
LROT_NUMENTRY( COMP_2CONV, ADS1115_CQUE_2CONV )
LROT_NUMENTRY( COMP_4CONV, ADS1115_CQUE_4CONV )
LROT_NUMENTRY( CMODE_TRAD, ADS1115_CMODE_TRAD )
LROT_NUMENTRY( CMODE_WINDOW, ADS1115_CMODE_WINDOW )
LROT_END(ads1115, NULL, 0 )
LROT_BEGIN(ads1115_instance)
LROT_FUNCENTRY( setting, ads1115_lua_setting )
LROT_FUNCENTRY( startread, ads1115_lua_startread )
LROT_FUNCENTRY( read, ads1115_lua_read )
#ifdef ADS1115_INCLUDE_TEST_FUNCTION
LROT_FUNCENTRY( test_volt_conversion, test_volt_conversion )
#endif
LROT_TABENTRY( __index, ads1115_instance )
LROT_FUNCENTRY( __gc, ads1115_lua_delete )
LROT_END(ads1115_instance, ads1115_instance, LROT_MASK_GC_INDEX )
int luaopen_ads1115(lua_State *L) {
luaL_rometatable(L, metatable_name, LROT_TABLEREF(ads1115_instance));
return 0;
}
NODEMCU_MODULE(ADS1115, "ads1115", ads1115, luaopen_ads1115);