diff --git a/README.md b/README.md index 5b1b43ba..716d3581 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,26 @@ home: [nodemcu.com](http://www.nodemcu.com)
bbs: [中文论坛Chinese bbs](http://bbs.nodemcu.com)
Tencent QQ group QQ群: 309957875
+# Summary +- Easy to access wireless router +- Based on Lua 5.1.4 (without *io, math, debug, os* module.) +- Event-Drive programming preferred. +- Build-in file, timer, pwm, i2c, 1-wire, net, gpio, wifi, adc, uart and system api. +- GPIO pin re-mapped, use the index to access gpio, i2c, pwm. + +# To Do List (pull requests are very welcomed) +- fix wifi smart connect +- add spi module +- add mqtt module +- add coap module + # Change log +2015-01-07
+retrive more ram back.
+add api file.format() to rebuild file system.
+rename "NodeMcu" to "NodeMCU" in firmware.
+add some check for file system op. + 2015-01-06
update sdk to 0.9.5.
pre_build bin now compiled by gcc toolchain.
@@ -20,22 +39,8 @@ memory/heap usage optimized.
add support for multiple platform and toolchain include eclipse.
combine firmware for 512K, 1M, 2M, 4M flash to one. flash size auto-detected. -2014-12-30
-modify uart.on api, when run_input set to 0, uart.on now can read raw data from uart.
-serial input now accept non-ascii chars.
-fix dev-kit gpio map.
-add setip, setmac, sleeptype api to wifi module.
-add tmr.time() api to get rtc time and calibration. - [more change log](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en#change_log)
[更多变更日志](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_cn#change_log) -# Summary -- Easy to access wireless router -- Based on Lua 5.1.4 -- Event-Drive programming preferred. -- Build-in file, timer, pwm, i2c, 1-wire, net, gpio, wifi, adc, uart and system api. -- GPIO pin re-mapped, use the index to access gpio, i2c, pwm. -- GPIO Map Table: ##GPIO NEW TABLE ( Build 20141219 and later) @@ -141,6 +146,7 @@ eagle.app.v6.irom0text.bin: 0x10000
esp_init_data_default.bin: 0x7c000
blank.bin: 0x7e000
+*Better run file.format() after flash* #Connect the hardware in serial baudrate:9600 diff --git a/app/driver/onewire.c b/app/driver/onewire.c index 18f46dca..73fe1b08 100644 --- a/app/driver/onewire.c +++ b/app/driver/onewire.c @@ -469,7 +469,8 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len) while (len--) { uint8_t inbyte = *addr++; - for (uint8_t i = 8; i; i--) { + uint8_t i; + for (i = 8; i; i--) { uint8_t mix = (crc ^ inbyte) & 0x01; crc >>= 1; if (mix) crc ^= 0x8C; diff --git a/app/include/driver/onewire.h b/app/include/driver/onewire.h index 9e1080b9..39429def 100644 --- a/app/include/driver/onewire.h +++ b/app/include/driver/onewire.h @@ -29,7 +29,7 @@ // old versions of OneWire). If you disable this, a slower // but very compact algorithm is used. #ifndef ONEWIRE_CRC8_TABLE -#define ONEWIRE_CRC8_TABLE 1 +#define ONEWIRE_CRC8_TABLE 0 #endif // You can allow 16-bit CRC checks by defining this to 1 diff --git a/app/include/user_config.h b/app/include/user_config.h index 5d821a9d..8e784520 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -6,8 +6,8 @@ #define NODE_VERSION_REVISION 5U #define NODE_VERSION_INTERNAL 0U -#define NODE_VERSION "NodeMcu 0.9.5" -#define BUILD_DATE "build 20150106" +#define NODE_VERSION "NodeMCU 0.9.5" +#define BUILD_DATE "build 20150107" // #define FLASH_512K // #define FLASH_1M diff --git a/app/lua/lobject.c b/app/lua/lobject.c index 13733b0c..73399e58 100644 --- a/app/lua/lobject.c +++ b/app/lua/lobject.c @@ -22,7 +22,7 @@ #include "lstring.h" #include "lvm.h" - +#include "flash_api.h" const TValue luaO_nilobject_ = {LUA_TVALUE_NIL}; @@ -52,7 +52,7 @@ int luaO_fb2int (int x) { int luaO_log2 (unsigned int x) { - static const lu_byte log_2[256] = { + static const lu_byte log_2[256] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, @@ -64,7 +64,8 @@ int luaO_log2 (unsigned int x) { }; int l = -1; while (x >= 256) { l += 8; x >>= 8; } - return l + log_2[x]; + // return l + log_2[x]; + return l + byte_of_aligned_array(log_2,x); } diff --git a/app/lua/lua.c b/app/lua/lua.c index 43325550..ef9113f4 100644 --- a/app/lua/lua.c +++ b/app/lua/lua.c @@ -133,7 +133,7 @@ static int docall (lua_State *L, int narg, int clear) { static void print_version (void) { // l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); - l_message(NULL, NODE_VERSION " " BUILD_DATE " powered by " LUA_RELEASE); + l_message(NULL, "\n" NODE_VERSION " " BUILD_DATE " powered by " LUA_RELEASE); } diff --git a/app/modules/file.c b/app/modules/file.c index 22782de3..fa7628d3 100644 --- a/app/modules/file.c +++ b/app/modules/file.c @@ -11,7 +11,7 @@ #include "flash_fs.h" #include "c_string.h" -static int file_fd = FS_OPEN_OK - 1; +static volatile int file_fd = FS_OPEN_OK - 1; // Lua: open(filename, mode) static int file_open( lua_State* L ) @@ -48,6 +48,22 @@ static int file_close( lua_State* L ) return 0; } +// Lua: format() +static int file_format( lua_State* L ) +{ + size_t len; + file_close(L); + if( !fs_format() ) + { + NODE_ERR( "\ni*** ERROR ***: unable to format. FS might be compromised.\n" ); + NODE_ERR( "It is advised to re-flash the NodeMCU image.\n" ); + } + else{ + NODE_ERR( "format done.\n" ); + } + return 0; +} + #if defined(BUILD_WOFS) // Lua: list() static int file_list( lua_State* L ) @@ -63,22 +79,6 @@ static int file_list( lua_State* L ) return 1; } -// Lua: format() -static int file_format( lua_State* L ) -{ - size_t len; - file_close(L); - if( !fs_format() ) - { - NODE_ERR( "\ni*** ERROR ***: unable to format. FS might be compromised.\n" ); - NODE_ERR( "It is advised to re-flash the nodeMcu image.\n" ); - } - else{ - NODE_ERR( "format done.\n" ); - } - return 0; -} - #elif defined(BUILD_SPIFFS) extern spiffs fs; @@ -275,8 +275,8 @@ const LUA_REG_TYPE file_map[] = { LSTRKEY( "writeline" ), LFUNCVAL( file_writeline ) }, { LSTRKEY( "read" ), LFUNCVAL( file_read ) }, { LSTRKEY( "readline" ), LFUNCVAL( file_readline ) }, -#if defined(BUILD_WOFS) { LSTRKEY( "format" ), LFUNCVAL( file_format ) }, +#if defined(BUILD_WOFS) #elif defined(BUILD_SPIFFS) { LSTRKEY( "remove" ), LFUNCVAL( file_remove ) }, { LSTRKEY( "seek" ), LFUNCVAL( file_seek ) }, diff --git a/app/platform/flash_api.c b/app/platform/flash_api.c index 11dba464..f98621ab 100644 --- a/app/platform/flash_api.c +++ b/app/platform/flash_api.c @@ -71,10 +71,10 @@ bool flash_set_size(uint8_t size) // Reboot required!!! // If you don't know what you're doing, your nodemcu may turn into stone ... uint8_t data[SPI_FLASH_SEC_SIZE] ICACHE_STORE_ATTR; - SPIRead(0, data, sizeof(data)); + spi_flash_read(0, (uint32 *)data, sizeof(data)); SPIFlashInfo *p_spi_flash_info = (SPIFlashInfo *)(data); p_spi_flash_info->size = size; - SPIEraseSector(0); + spi_flash_erase_sector(0); spi_flash_write(0, (uint32 *)data, sizeof(data)); //p_spi_flash_info = flash_get_info(); //p_spi_flash_info->size = size; @@ -175,13 +175,13 @@ uint32_t flash_get_speed(void) bool flash_init_data_written(void) { // FLASH SEC - 4 - // Dangerous, here are dinosaur infested!!!!! - // Reboot required!!! - // It will init system data to default! uint32_t data[2] ICACHE_STORE_ATTR; - SPIRead((flash_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, data, sizeof(data)); - if(data[0] == 0xFFFFFFFF && data[1] == 0xFFFFFFFF) { - return false; + if (SPI_FLASH_RESULT_OK == spi_flash_read((flash_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)data, sizeof(data))) + { + if (data[0] == 0xFFFFFFFF && data[1] == 0xFFFFFFFF) + { + return false; + } } return true; } @@ -192,10 +192,15 @@ bool flash_init_data_default(void) // Dangerous, here are dinosaur infested!!!!! // Reboot required!!! // It will init system data to default! - - SPIEraseSector((flash_get_sec_num() - 4)); - spi_flash_write((flash_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)flash_init_data, 128); - return true; + bool result = false; + if (SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_get_sec_num() - 4))) + { + if (SPI_FLASH_RESULT_OK == spi_flash_write((flash_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)flash_init_data, 128)) + { + result = true; + } + } + return result; } bool flash_init_data_blank(void) @@ -204,14 +209,30 @@ bool flash_init_data_blank(void) // Dangerous, here are dinosaur infested!!!!! // Reboot required!!! // It will init system config to blank! - SPIEraseSector((flash_get_sec_num() - 2)); - SPIEraseSector((flash_get_sec_num() - 1)); - return true; + bool result = false; + if ((SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_get_sec_num() - 2))) && + (SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_get_sec_num() - 1)))) + { + result = true; + } + + return result ; } bool flash_self_destruct(void) { - // Erase your flash. Good bye! + // Dangerous, Erase your flash. Good bye! SPIEraseChip(); return true; } + +uint8_t byte_of_aligned_array(const uint8_t* aligned_array, uint32_t index) +{ + if( (((uint32_t)aligned_array)%4) != 0 ){ + NODE_DBG("aligned_array is not 4-byte aligned.\n"); + return 0; + } + uint32_t v = ((uint32_t *)aligned_array)[ index/4 ]; + uint8_t *p = (uint8_t *) (&v); + return p[ (index%4) ]; +} diff --git a/app/platform/flash_api.h b/app/platform/flash_api.h index 593741c8..929ca998 100644 --- a/app/platform/flash_api.h +++ b/app/platform/flash_api.h @@ -5,6 +5,28 @@ #include "cpu_esp8266.h" #define FLASH_MAP_START_ADDRESS (INTERNAL_FLASH_START_ADDRESS) +/****************************************************************************** + * ROM Function definition + * Note: It is unsafe to use ROM function, but it may efficient. + * SPIEraseSector + * unknown SPIEraseSector(uint16 sec); + * The 1st parameter is flash sector number. + + * SPIRead (Unsafe) + * unknown SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size); + * The 1st parameter is source addresses. + * The 2nd parameter is destination addresses. + * The 3rd parameter is size. + * Note: Sometimes it have no effect, may be need a delay or other option(lock or unlock, etc.) with known reason. + + * SPIWrite (Unsafe) + * unknown SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size); + * The 1st parameter is destination addresses. + * The 2nd parameter is source addresses. + * The 3rd parameter is size. + * Note: Sometimes it have no effect, may be need a delay or other option(lock or unlock, etc.) with known reason. +*******************************************************************************/ + typedef struct { uint8_t unknown0; @@ -45,5 +67,6 @@ bool flash_init_data_written(void); bool flash_init_data_default(void); bool flash_init_data_blank(void); bool flash_self_destruct(void); +uint8_t byte_of_aligned_array(const uint8_t* aligned_array, uint32_t index); #endif // __FLASH_API_H__ diff --git a/app/spiffs/spiffs.c b/app/spiffs/spiffs.c index 005dab1a..84d57008 100644 --- a/app/spiffs/spiffs.c +++ b/app/spiffs/spiffs.c @@ -81,6 +81,7 @@ int myspiffs_format( void ) while( sect_first <= sect_last ) if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR ) return 0; + spiffs_mount(); return 1; } @@ -107,10 +108,20 @@ size_t myspiffs_write( int fd, const void* ptr, size_t len ){ return len; } #endif - return SPIFFS_write(&fs, (spiffs_file)fd, (void *)ptr, len); + int res = SPIFFS_write(&fs, (spiffs_file)fd, (void *)ptr, len); + if (res < 0) { + NODE_DBG("write errno %i\n", SPIFFS_errno(&fs)); + return 0; + } + return res; } size_t myspiffs_read( int fd, void* ptr, size_t len){ - return SPIFFS_read(&fs, (spiffs_file)fd, ptr, len); + int res = SPIFFS_read(&fs, (spiffs_file)fd, ptr, len); + if (res < 0) { + NODE_DBG("read errno %i\n", SPIFFS_errno(&fs)); + return 0; + } + return res; } int myspiffs_lseek( int fd, int off, int whence ){ return SPIFFS_lseek(&fs, (spiffs_file)fd, off, whence); @@ -123,8 +134,13 @@ int myspiffs_tell( int fd ){ } int myspiffs_getc( int fd ){ char c = EOF; + int res; if(!myspiffs_eof(fd)){ - SPIFFS_read(&fs, (spiffs_file)fd, &c, 1); + res = SPIFFS_read(&fs, (spiffs_file)fd, &c, 1); + if (res != 1) { + NODE_DBG("getc errno %i\n", SPIFFS_errno(&fs)); + return (int)EOF; + } } return (int)c; } diff --git a/app/ssl/crypto/ssl_aes.c b/app/ssl/crypto/ssl_aes.c index efaa7a58..6765779c 100644 --- a/app/ssl/crypto/ssl_aes.c +++ b/app/ssl/crypto/ssl_aes.c @@ -81,7 +81,7 @@ /* * AES S-box */ -static const uint8_t aes_sbox[256] = +static const uint8_t aes_sbox[256] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = { 0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5, 0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76, @@ -120,7 +120,7 @@ static const uint8_t aes_sbox[256] = /* * AES is-box */ -static const uint8_t aes_isbox[256] = +static const uint8_t aes_isbox[256] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = { 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38, 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, @@ -226,20 +226,28 @@ void ICACHE_FLASH_ATTR AES_set_key(AES_CTX *ctx, const uint8_t *key, if ((i % words) == 0) { - tmp2 =(uint32_t)aes_sbox[(tmp )&0xff]<< 8; - tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<<16; - tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<24; - tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]; + // tmp2 =(uint32_t)aes_sbox[(tmp )&0xff]<< 8; + // tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<<16; + // tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<24; + // tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]; + tmp2 =((uint32_t)byte_of_aligned_array(aes_sbox,(tmp )&0xff))<< 8; + tmp2|=((uint32_t)byte_of_aligned_array(aes_sbox,(tmp>> 8)&0xff))<<16; + tmp2|=((uint32_t)byte_of_aligned_array(aes_sbox,(tmp>>16)&0xff))<<24; + tmp2|=((uint32_t)byte_of_aligned_array(aes_sbox,(tmp>>24) )); tmp=tmp2^(((unsigned int)*ip)<<24); ip++; } if ((words == 8) && ((i % words) == 4)) { - tmp2 =(uint32_t)aes_sbox[(tmp )&0xff] ; - tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<< 8; - tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<16; - tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]<<24; + // tmp2 =(uint32_t)aes_sbox[(tmp )&0xff] ; + // tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<< 8; + // tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<16; + // tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]<<24; + tmp2 =((uint32_t)byte_of_aligned_array(aes_sbox,(tmp )&0xff)) ; + tmp2|=((uint32_t)byte_of_aligned_array(aes_sbox,(tmp>> 8)&0xff))<< 8; + tmp2|=((uint32_t)byte_of_aligned_array(aes_sbox,(tmp>>16)&0xff))<<16; + tmp2|=((uint32_t)byte_of_aligned_array(aes_sbox,(tmp>>24) ))<<24; tmp=tmp2; } @@ -375,10 +383,15 @@ static void ICACHE_FLASH_ATTR AES_encrypt(const AES_CTX *ctx, uint32_t *data) /* Perform ByteSub and ShiftRow operations together */ for (row = 0; row < 4; row++) { - a0 = (uint32_t)aes_sbox[(data[row%4]>>24)&0xFF]; - a1 = (uint32_t)aes_sbox[(data[(row+1)%4]>>16)&0xFF]; - a2 = (uint32_t)aes_sbox[(data[(row+2)%4]>>8)&0xFF]; - a3 = (uint32_t)aes_sbox[(data[(row+3)%4])&0xFF]; + // a0 = (uint32_t)aes_sbox[(data[row%4]>>24)&0xFF]; + // a1 = (uint32_t)aes_sbox[(data[(row+1)%4]>>16)&0xFF]; + // a2 = (uint32_t)aes_sbox[(data[(row+2)%4]>>8)&0xFF]; + // a3 = (uint32_t)aes_sbox[(data[(row+3)%4])&0xFF]; + + a0 = (uint32_t)(byte_of_aligned_array(aes_sbox,(data[row%4]>>24)&0xFF)); + a1 = (uint32_t)(byte_of_aligned_array(aes_sbox,(data[(row+1)%4]>>16)&0xFF)); + a2 = (uint32_t)(byte_of_aligned_array(aes_sbox,(data[(row+2)%4]>>8)&0xFF)); + a3 = (uint32_t)(byte_of_aligned_array(aes_sbox,(data[(row+3)%4])&0xFF)); /* Perform MixColumn iff not last round */ if (curr_rnd < (rounds - 1)) @@ -423,10 +436,15 @@ static void ICACHE_FLASH_ATTR AES_decrypt(const AES_CTX *ctx, uint32_t *data) /* Perform ByteSub and ShiftRow operations together */ for (row = 4; row > 0; row--) { - a0 = aes_isbox[(data[(row+3)%4]>>24)&0xFF]; - a1 = aes_isbox[(data[(row+2)%4]>>16)&0xFF]; - a2 = aes_isbox[(data[(row+1)%4]>>8)&0xFF]; - a3 = aes_isbox[(data[row%4])&0xFF]; + // a0 = aes_isbox[(data[(row+3)%4]>>24)&0xFF]; + // a1 = aes_isbox[(data[(row+2)%4]>>16)&0xFF]; + // a2 = aes_isbox[(data[(row+1)%4]>>8)&0xFF]; + // a3 = aes_isbox[(data[row%4])&0xFF]; + + a0 = byte_of_aligned_array(aes_isbox,(data[(row+3)%4]>>24)&0xFF); + a1 = byte_of_aligned_array(aes_isbox,(data[(row+2)%4]>>16)&0xFF); + a2 = byte_of_aligned_array(aes_isbox,(data[(row+1)%4]>>8)&0xFF); + a3 = byte_of_aligned_array(aes_isbox,(data[row%4])&0xFF); /* Perform MixColumn iff not last round */ if (curr_rnd<(rounds-1)) diff --git a/app/user/user_main.c b/app/user/user_main.c index bc044cd5..77c7939e 100644 --- a/app/user/user_main.c +++ b/app/user/user_main.c @@ -83,9 +83,12 @@ void user_init(void) return; } - if(!flash_init_data_written()){ + if( !flash_init_data_written() ){ NODE_ERR("Restore init data.\n"); + // Flash init data at FLASHSIZE - 0x04000 Byte. flash_init_data_default(); + // Flash blank data at FLASHSIZE - 0x02000 Byte. + flash_init_data_blank(); } #if defined( BUILD_WOFS ) diff --git a/examples/fragment.lua b/examples/fragment.lua index f4f8b11d..0699df4e 100644 --- a/examples/fragment.lua +++ b/examples/fragment.lua @@ -310,3 +310,5 @@ uart.on("data", 5 ,function(input) if input=="quit\r" then uart.on("data") else uart.on("data", 0 ,function(input) if input=="q" then uart.on("data") else print(input) end end, 0) uart.on("data","\r",function(input) if input=="quit" then uart.on("data") else print(input) end end, 1) + +for k, v in pairs(file.list()) do print('file:'..k..' len:'..v) end diff --git a/pre_build/0.9.5/nodemcu_latest.bin b/pre_build/0.9.5/nodemcu_latest.bin index 7b13f9cd..04f4dc31 100644 Binary files a/pre_build/0.9.5/nodemcu_latest.bin and b/pre_build/0.9.5/nodemcu_latest.bin differ diff --git a/pre_build/latest/nodemcu_512k_latest.bin b/pre_build/latest/nodemcu_512k_latest.bin index 7b13f9cd..04f4dc31 100644 Binary files a/pre_build/latest/nodemcu_512k_latest.bin and b/pre_build/latest/nodemcu_512k_latest.bin differ diff --git a/pre_build/latest/nodemcu_latest.bin b/pre_build/latest/nodemcu_latest.bin index 7b13f9cd..04f4dc31 100644 Binary files a/pre_build/latest/nodemcu_latest.bin and b/pre_build/latest/nodemcu_latest.bin differ