diff --git a/app/include/user_modules.h b/app/include/user_modules.h index 688c7bcd..18fc5cfa 100644 --- a/app/include/user_modules.h +++ b/app/include/user_modules.h @@ -39,6 +39,7 @@ #define LUA_USE_MODULES_RTCTIME #define LUA_USE_MODULES_RTCFIFO #define LUA_USE_MODULES_SNTP +//#define LUA_USE_MODULES_BMP085 #endif /* LUA_USE_MODULES */ diff --git a/app/modules/bmp085.c b/app/modules/bmp085.c new file mode 100644 index 00000000..9d9543de --- /dev/null +++ b/app/modules/bmp085.c @@ -0,0 +1,200 @@ +#include "lualib.h" +#include "lauxlib.h" +#include "platform.h" +#include "auxmods.h" +#include "lrotable.h" +#include "c_stdlib.h" +#include "c_string.h" + +static const uint32_t bmp085_i2c_id = 0; +static const uint8_t bmp085_i2c_addr = 0x77; + +static struct { + int16_t AC1; + int16_t AC2; + int16_t AC3; + uint16_t AC4; + uint16_t AC5; + uint16_t AC6; + int16_t B1; + int16_t B2; + int16_t MB; + int16_t MC; + int16_t MD; +} bmp085_data; + +static uint8_t ICACHE_FLASH_ATTR r8u(uint32_t id, uint8_t reg) { + uint8_t ret; + + platform_i2c_send_start(id); + platform_i2c_send_address(id, bmp085_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER); + platform_i2c_send_byte(id, reg); + platform_i2c_send_stop(id); + platform_i2c_send_start(id); + platform_i2c_send_address(id, bmp085_i2c_addr, PLATFORM_I2C_DIRECTION_RECEIVER); + ret = platform_i2c_recv_byte(id, 0); + platform_i2c_send_stop(id); + return ret; +} + +static uint16_t ICACHE_FLASH_ATTR r16u(uint32_t id, uint8_t reg) { + uint8_t high = r8u(id, reg); + uint8_t low = r8u(id, reg + 1); + return (high << 8) | low; +} + +static int16_t ICACHE_FLASH_ATTR r16(uint32_t id, uint8_t reg) { + return (int16_t) r16u(id, reg); +} + +static int ICACHE_FLASH_ATTR bmp085_init(lua_State* L) { + uint32_t sda; + uint32_t scl; + + 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"); + } + + platform_i2c_setup(bmp085_i2c_id, sda, scl, PLATFORM_I2C_SPEED_SLOW); + + bmp085_data.AC1 = r16(bmp085_i2c_id, 0xAA); + bmp085_data.AC2 = r16(bmp085_i2c_id, 0xAC); + bmp085_data.AC3 = r16(bmp085_i2c_id, 0xAE); + bmp085_data.AC4 = r16u(bmp085_i2c_id, 0xB0); + bmp085_data.AC5 = r16u(bmp085_i2c_id, 0xB2); + bmp085_data.AC6 = r16u(bmp085_i2c_id, 0xB4); + bmp085_data.B1 = r16(bmp085_i2c_id, 0xB6); + bmp085_data.B2 = r16(bmp085_i2c_id, 0xB8); + bmp085_data.MB = r16(bmp085_i2c_id, 0xBA); + bmp085_data.MC = r16(bmp085_i2c_id, 0xBC); + bmp085_data.MD = r16(bmp085_i2c_id, 0xBE); + + return 1; +} + +static int16_t ICACHE_FLASH_ATTR bmp085_temperature(void) { + int16_t t, X1, X2; + + platform_i2c_send_start(bmp085_i2c_id); + platform_i2c_send_address(bmp085_i2c_id, bmp085_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER); + platform_i2c_send_byte(bmp085_i2c_id, 0xF4); + platform_i2c_send_byte(bmp085_i2c_id, 0x2E); + platform_i2c_send_stop(bmp085_i2c_id); + + // Wait for device to complete sampling + os_delay_us(4500); + + t = r16(bmp085_i2c_id, 0xF6); + X1 = ((t - bmp085_data.AC6) * bmp085_data.AC5) >> 15; + X2 = (bmp085_data.MC << 11)/ (X1 + bmp085_data.MD); + t = (X2 + X1 + 8) >> 4; + return t; +} + +static int ICACHE_FLASH_ATTR bmp085_lua_temperature(lua_State* L) { + lua_pushinteger(L, bmp085_temperature()); + return 1; +} + +static int32_t ICACHE_FLASH_ATTR bmp085_pressure_raw(int oss) { + int32_t p; + int32_t p1, p2, p3; + + platform_i2c_send_start(bmp085_i2c_id); + platform_i2c_send_address(bmp085_i2c_id, bmp085_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER); + platform_i2c_send_byte(bmp085_i2c_id, 0xF4); + platform_i2c_send_byte(bmp085_i2c_id, 0x34 + 64 * oss); + platform_i2c_send_stop(bmp085_i2c_id); + + // Wait for device to complete sampling + switch (oss) { + case 0: os_delay_us( 4500); break; + case 1: os_delay_us( 7500); break; + case 2: os_delay_us(13500); break; + case 3: os_delay_us(25500); break; + } + + p1 = r8u(bmp085_i2c_id, 0xF6); + p2 = r8u(bmp085_i2c_id, 0xF7); + p3 = r8u(bmp085_i2c_id, 0xF8); + p = (p1 << 16) | (p2 << 8) | p3; + p = p >> (8 - oss); + + return p; +} + +static int ICACHE_FLASH_ATTR bmp085_lua_pressure_raw(lua_State* L) { + uint8_t oss = 0; + int32_t p; + + if (lua_isnumber(L, 1)) { + oss = luaL_checkinteger(L, 1); + if (oss > 3) { + oss = 3; + } + } + + p = bmp085_pressure_raw(oss); + lua_pushinteger(L, p); + return 1; +} + +static int ICACHE_FLASH_ATTR bmp085_lua_pressure(lua_State* L) { + uint8_t oss = 0; + int32_t p, t; + int32_t X1, X2, X3, B3, B4, B5, B6, B7; + + if (lua_isnumber(L, 1)) { + oss = luaL_checkinteger(L, 1); + if (oss > 3) { + oss = 3; + } + } + + p = bmp085_pressure_raw(oss); + t = bmp085_temperature(); + + B5 = (t << 4) - 8; + B6 = B5 - 4000; + X1 = ((int32_t)bmp085_data.B2 * ((B6 * B6) >> 12)) >> 11; + X2 = ((int32_t)bmp085_data.AC2 * B6) >> 11; + X3 = X1 + X2; + B3 = ((((int32_t)bmp085_data.AC1 << 2) + X3) * (1 << oss) + 2) >> 2; + X1 = ((int32_t)bmp085_data.AC3 * B6) >> 13; + X2 = ((int32_t)bmp085_data.B1 * ((B6 * B6) >> 12)) >> 16; + X3 = (X1 + X2 + 2) >> 2; + B4 = ((int32_t)bmp085_data.AC4 * (X3 + 32768)) >> 15; + B7 = (p - B3) * (50000 / (1 << oss)); + p = (B7 / B4) << 1; + X1 = (p >> 8) * (p >> 8); + X1 = (X1 * 3038) >> 16; + X2 = (-7357 * p) >> 16; + p = p + ((X1 + X2 + 3791) >> 4); + + lua_pushinteger(L, p); + return 1; +} + +#define MIN_OPT_LEVEL 2 +#include "lrodefs.h" +const LUA_REG_TYPE bmp085_map[] = +{ + { LSTRKEY( "temperature" ), LFUNCVAL( bmp085_lua_temperature )}, + { LSTRKEY( "pressure" ), LFUNCVAL( bmp085_lua_pressure )}, + { LSTRKEY( "pressure_raw" ), LFUNCVAL( bmp085_lua_pressure_raw )}, + { LSTRKEY( "init" ), LFUNCVAL( bmp085_init )}, + { LNILKEY, LNILVAL} +}; + +LUALIB_API int luaopen_bmp085(lua_State *L) { + LREGISTER(L, "bmp085", bmp085_map); + return 1; +} + diff --git a/app/modules/modules.h b/app/modules/modules.h index 1bb26fb5..176f4591 100644 --- a/app/modules/modules.h +++ b/app/modules/modules.h @@ -213,6 +213,15 @@ #define ROM_MODULES_SNTP #endif +#if defined(LUA_USE_MODULES_BMP085) +#define MODULES_BMP085 "bmp085" +#define ROM_MODULES_BMP085 \ + _ROM(MODULES_BMP085, luaopen_bmp085, bmp085_map) +#else +#define ROM_MODULES_BMP085 +#endif + + #define LUA_MODULES_ROM \ ROM_MODULES_GPIO \ ROM_MODULES_PWM \ @@ -240,5 +249,6 @@ ROM_MODULES_RTCTIME \ ROM_MODULES_RTCFIFO \ ROM_MODULES_SNTP \ + ROM_MODULES_BMP085 \ #endif