diff --git a/app/include/user_config.h b/app/include/user_config.h index f5d33fb9..b6686004 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -47,6 +47,8 @@ // #define BUILD_WOFS 1 #define BUILD_SPIFFS 1 +#define SPIFFS_CACHE 1 + // #define LUA_NUMBER_INTEGRAL #define LUA_OPTRAM 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/lwip/app/dhcpserver.c b/app/lwip/app/dhcpserver.c index e2a05f06..017f9738 100644 --- a/app/lwip/app/dhcpserver.c +++ b/app/lwip/app/dhcpserver.c @@ -145,7 +145,7 @@ static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) *optptr++ = ip4_addr3( &ipadd); *optptr++ = ip4_addr4( &ipadd); -#ifdef USE_DNS +#if USE_DNS *optptr++ = DHCP_OPTION_DNS_SERVER; *optptr++ = 4; *optptr++ = ip4_addr1( &ipadd); @@ -154,7 +154,7 @@ static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) *optptr++ = ip4_addr4( &ipadd); #endif -#ifdef CLASS_B_NET +#ifdef USE_CLASS_B_NET *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; *optptr++ = 4; *optptr++ = ip4_addr1( &ipadd); @@ -172,7 +172,7 @@ static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) *optptr++ = DHCP_OPTION_INTERFACE_MTU; *optptr++ = 2; -#ifdef CLASS_B_NET +#ifdef USE_CLASS_B_NET *optptr++ = 0x05; *optptr++ = 0xdc; #else diff --git a/app/lwip/core/dns.c b/app/lwip/core/dns.c index ab6821f2..1fe7aaa4 100644 --- a/app/lwip/core/dns.c +++ b/app/lwip/core/dns.c @@ -173,7 +173,7 @@ struct dns_table_entry { u8_t seqno; u8_t err; u32_t ttl; - char name[DNS_MAX_NAME_LENGTH]; + char *name; ip_addr_t ipaddr; /* pointer to callback on DNS query done */ dns_found_callback found; @@ -673,6 +673,8 @@ dns_check_entry(u8_t i) if (pEntry->found) (*pEntry->found)(pEntry->name, NULL, pEntry->arg); /* flush this entry */ + mem_free (pEntry->name); + pEntry->name = NULL; pEntry->state = DNS_STATE_UNUSED; pEntry->found = NULL; break; @@ -697,6 +699,8 @@ dns_check_entry(u8_t i) if (--pEntry->ttl == 0) { LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", pEntry->name)); /* flush this entry */ + mem_free (pEntry->name); + pEntry->name = NULL; pEntry->state = DNS_STATE_UNUSED; pEntry->found = NULL; } @@ -839,6 +843,8 @@ responseerr: (*pEntry->found)(pEntry->name, NULL, pEntry->arg); } /* flush this entry */ + mem_free (pEntry->name); + pEntry->name = NULL; pEntry->state = DNS_STATE_UNUSED; pEntry->found = NULL; @@ -898,11 +904,16 @@ dns_enqueue(const char *name, dns_found_callback found, void *callback_arg) LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i))); /* fill the entry */ + namelen = LWIP_MIN(strlen(name), DNS_MAX_NAME_LENGTH-1); + char *namebuf = (char *)mem_zalloc (namelen); + if (!namebuf) + return ERR_MEM; pEntry->state = DNS_STATE_NEW; pEntry->seqno = dns_seqno++; pEntry->found = found; pEntry->arg = callback_arg; - namelen = LWIP_MIN(strlen(name), DNS_MAX_NAME_LENGTH-1); + mem_free (pEntry->name); + pEntry->name = namebuf; MEMCPY(pEntry->name, name, namelen); pEntry->name[namelen] = 0; 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/file.c b/app/modules/file.c index d055ef87..b4a9cfa0 100644 --- a/app/modules/file.c +++ b/app/modules/file.c @@ -196,11 +196,10 @@ static int file_fsinfo( lua_State* L ) // g_read() static int file_g_read( lua_State* L, int n, int16_t end_char ) { - if(n< 0 || n>LUAL_BUFFERSIZE) + if(n <= 0 || n > LUAL_BUFFERSIZE) n = LUAL_BUFFERSIZE; if(end_char < 0 || end_char >255) end_char = EOF; - int ec = (int)end_char; luaL_Buffer b; if((FS_OPEN_OK - 1)==file_fd) @@ -208,27 +207,22 @@ static int file_g_read( lua_State* L, int n, int16_t end_char ) luaL_buffinit(L, &b); char *p = luaL_prepbuffer(&b); - int c = EOF; - int i = 0; + int i; - do{ - c = fs_getc(file_fd); - if(c==EOF){ + n = fs_read(file_fd, p, n); + for (i = 0; i < n; ++i) + if (p[i] == end_char) + { + ++i; break; } - p[i++] = (char)(0xFF & c); - }while((c!=EOF) && (c!=ec) && (i0 && p[i-1] == '\n') - i--; /* do not include `eol' */ -#endif - if(i==0){ luaL_pushresult(&b); /* close buffer */ return (lua_objlen(L, -1) > 0); /* check whether read something */ } + fs_seek(file_fd, -(n - i), SEEK_CUR); luaL_addsize(&b, i); luaL_pushresult(&b); /* close buffer */ return 1; /* read at least an `eol' */ 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 diff --git a/app/platform/common.c b/app/platform/common.c index 711a8a4a..617f6831 100644 --- a/app/platform/common.c +++ b/app/platform/common.c @@ -220,7 +220,7 @@ uint32_t platform_flash_read( void *to, uint32_t fromaddr, uint32_t size ) #else // #ifindef INTERNAL_FLASH_READ_UNIT_SIZE uint32_t temp, rest, ssize = size; unsigned i; - char tmpdata[ INTERNAL_FLASH_READ_UNIT_SIZE ]; + char tmpdata[ INTERNAL_FLASH_READ_UNIT_SIZE ] __attribute__ ((aligned(INTERNAL_FLASH_READ_UNIT_SIZE))); uint8_t *pto = ( uint8_t* )to; const uint32_t blksize = INTERNAL_FLASH_READ_UNIT_SIZE; const uint32_t blkmask = INTERNAL_FLASH_READ_UNIT_SIZE - 1; diff --git a/app/platform/platform.c b/app/platform/platform.c index 40aa50ad..b31d55e7 100644 --- a/app/platform/platform.c +++ b/app/platform/platform.c @@ -460,13 +460,19 @@ spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data ) // **************************************************************************** // Flash access functions +/* + * Assumptions: + * > toaddr is INTERNAL_FLASH_WRITE_UNIT_SIZE aligned + * > size is a multiple of INTERNAL_FLASH_WRITE_UNIT_SIZE + */ uint32_t platform_s_flash_write( const void *from, uint32_t toaddr, uint32_t size ) { toaddr -= INTERNAL_FLASH_START_ADDRESS; SpiFlashOpResult r; const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1; uint32_t *apbuf = NULL; - if( ((uint32_t)from) & blkmask ){ + uint32_t fromaddr = (uint32_t)from; + if( (fromaddr & blkmask ) || (fromaddr >= INTERNAL_FLASH_START_ADDRESS)) { apbuf = (uint32_t *)c_malloc(size); if(!apbuf) return 0; @@ -484,12 +490,37 @@ uint32_t platform_s_flash_write( const void *from, uint32_t toaddr, uint32_t siz } } +/* + * Assumptions: + * > fromaddr is INTERNAL_FLASH_READ_UNIT_SIZE aligned + * > size is a multiple of INTERNAL_FLASH_READ_UNIT_SIZE + */ uint32_t platform_s_flash_read( void *to, uint32_t fromaddr, uint32_t size ) { + if (size==0) + return 0; + fromaddr -= INTERNAL_FLASH_START_ADDRESS; SpiFlashOpResult r; WRITE_PERI_REG(0x60000914, 0x73); - r = flash_read(fromaddr, (uint32 *)to, size); + + const uint32_t blkmask = (INTERNAL_FLASH_READ_UNIT_SIZE - 1); + if( ((uint32_t)to) & blkmask ) + { + uint32_t size2=size-INTERNAL_FLASH_READ_UNIT_SIZE; + uint32* to2=(uint32*)((((uint32_t)to)&(~blkmask))+INTERNAL_FLASH_READ_UNIT_SIZE); + r = flash_read(fromaddr, to2, size2); + if(SPI_FLASH_RESULT_OK == r) + { + os_memmove(to,to2,size2); + char back[ INTERNAL_FLASH_READ_UNIT_SIZE ] __attribute__ ((aligned(INTERNAL_FLASH_READ_UNIT_SIZE))); + r=flash_read(fromaddr+size2,(uint32*)back,INTERNAL_FLASH_READ_UNIT_SIZE); + os_memcpy((uint8_t*)to+size2,back,INTERNAL_FLASH_READ_UNIT_SIZE); + } + } + else + r = flash_read(fromaddr, (uint32 *)to, size); + if(SPI_FLASH_RESULT_OK == r) return size; else{ diff --git a/app/spiffs/spiffs.c b/app/spiffs/spiffs.c index bcb11d5c..bae70860 100644 --- a/app/spiffs/spiffs.c +++ b/app/spiffs/spiffs.c @@ -8,7 +8,9 @@ spiffs fs; static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2]; static u8_t spiffs_fds[32*4]; -static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*4]; +#if SPIFFS_CACHE +static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*2]; +#endif static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst) { platform_flash_read(dst, addr, size); @@ -62,8 +64,12 @@ void myspiffs_mount() { spiffs_work_buf, spiffs_fds, sizeof(spiffs_fds), +#if SPIFFS_CACHE spiffs_cache, sizeof(spiffs_cache), +#else + 0, 0, +#endif // myspiffs_check_callback); 0); NODE_DBG("mount res: %i\n", res); diff --git a/app/spiffs/spiffs_config.h b/app/spiffs/spiffs_config.h index 0dc19958..52d6b9d9 100644 --- a/app/spiffs/spiffs_config.h +++ b/app/spiffs/spiffs_config.h @@ -8,16 +8,10 @@ #ifndef SPIFFS_CONFIG_H_ #define SPIFFS_CONFIG_H_ -// ----------- 8< ------------ -// Following includes are for the linux test build of spiffs -// These may/should/must be removed/altered/replaced in your target -// #include "params_test.h" +#include "user_config.h" #include "c_stdio.h" -#include "c_stdlib.h" +#include "c_stdint.h" #include "c_string.h" -#include "c_stddef.h" -#include "c_types.h" -// ----------- >8 ------------ typedef sint32_t s32_t; typedef uint32_t u32_t; @@ -67,6 +61,8 @@ typedef uint8_t u8_t; #ifndef SPIFFS_CACHE_STATS #define SPIFFS_CACHE_STATS 0 #endif +#else +#define SPIFFS_CACHE_WR 0 #endif // Always check header of each accessed page to ensure consistent state. diff --git a/app/spiffs/spiffs_nucleus.h b/app/spiffs/spiffs_nucleus.h index 02ba7a96..c5c3b9e4 100644 --- a/app/spiffs/spiffs_nucleus.h +++ b/app/spiffs/spiffs_nucleus.h @@ -415,7 +415,7 @@ typedef struct __attribute(( packed )) { } spiffs_page_header; // object index header page header -typedef struct __attribute(( packed, aligned(4) )) +typedef struct __attribute(( packed )) { // common page header spiffs_page_header p_hdr; @@ -428,7 +428,7 @@ typedef struct __attribute(( packed, aligned(4) )) } spiffs_page_object_ix_header; // object index page header -typedef struct __attribute(( packed, aligned(4) )) { +typedef struct __attribute(( packed )) { spiffs_page_header p_hdr; } spiffs_page_object_ix;