Browse Source

ROM flash size can changed with detected size, fixed #283.

HuangRui 9 years ago
parent
commit
5c84359b5c
4 changed files with 178 additions and 97 deletions
  1. 67 72
      app/modules/node.c
  2. 89 20
      app/platform/flash_api.c
  3. 9 4
      app/platform/flash_api.h
  4. 13 1
      app/user/user_main.c

+ 67 - 72
app/modules/node.c

@@ -29,7 +29,7 @@
 static int node_restart( lua_State* L )
 {
   system_restart();
-  return 0;  
+  return 0;
 }
 
 // Lua: dsleep( us, option )
@@ -56,7 +56,7 @@ static int node_deepsleep( lua_State* L )
     else
       system_deep_sleep( us );
   }
-  return 0;  
+  return 0;
 }
 
 // Lua: dsleep_set_options
@@ -80,14 +80,14 @@ static int node_info( lua_State* L )
   lua_pushinteger(L, NODE_VERSION_REVISION);
   lua_pushinteger(L, system_get_chip_id());   // chip id
   lua_pushinteger(L, spi_flash_get_id());     // flash id
-  #if defined(FLASH_SAFE_API)
+#if defined(FLASH_SAFE_API)
   lua_pushinteger(L, flash_safe_get_size_byte() / 1024);  // flash size in KB
-  #else
+#else
   lua_pushinteger(L, flash_rom_get_size_byte() / 1024);  // flash size in KB
-  #endif // defined(FLASH_SAFE_API)
+#endif // defined(FLASH_SAFE_API)
   lua_pushinteger(L, flash_rom_get_mode());
   lua_pushinteger(L, flash_rom_get_speed());
-  return 8;  
+  return 8;
 }
 
 // Lua: chipid()
@@ -95,7 +95,7 @@ static int node_chipid( lua_State* L )
 {
   uint32_t id = system_get_chip_id();
   lua_pushinteger(L, id);
-  return 1;  
+  return 1;
 }
 // Lua: readvdd33()
 static int node_readvdd33( lua_State* L )
@@ -110,28 +110,23 @@ static int node_flashid( lua_State* L )
 {
   uint32_t id = spi_flash_get_id();
   lua_pushinteger( L, id );
-  return 1;  
+  return 1;
 }
 
 // Lua: flashsize()
 static int node_flashsize( lua_State* L )
 {
-  //uint32_t sz = 0;
-  //if(lua_type(L, 1) == LUA_TNUMBER)
-  //{
-  //  sz = luaL_checkinteger(L, 1);
-  //  if(sz > 0)
-  //  {
-  //    flash_set_size_byte(sz);
-  //  }
-  //}
+  if (lua_type(L, 1) == LUA_TNUMBER)
+  {
+    flash_rom_set_size_byte(luaL_checkinteger(L, 1));
+  }
 #if defined(FLASH_SAFE_API)
   uint32_t sz = flash_safe_get_size_byte();
 #else
   uint32_t sz = flash_rom_get_size_byte();
 #endif // defined(FLASH_SAFE_API)
   lua_pushinteger( L, sz );
-  return 1;  
+  return 1;
 }
 
 // Lua: heap()
@@ -139,7 +134,7 @@ static int node_heap( lua_State* L )
 {
   uint32_t sz = system_get_free_heap_size();
   lua_pushinteger(L, sz);
-  return 1;  
+  return 1;
 }
 
 static lua_State *gL = NULL;
@@ -154,7 +149,7 @@ static int node_led( lua_State* L )
   if ( lua_isnumber(L, 1) )
   {
     low = lua_tointeger(L, 1);
-    if ( low < 0 ){
+    if ( low < 0 ) {
       return luaL_error( L, "wrong arg type" );
     }
   } else {
@@ -163,7 +158,7 @@ static int node_led( lua_State* L )
   if ( lua_isnumber(L, 2) )
   {
     high = lua_tointeger(L, 2);
-    if ( high < 0 ){
+    if ( high < 0 ) {
       return luaL_error( L, "wrong arg type" );
     }
   } else {
@@ -171,14 +166,14 @@ static int node_led( lua_State* L )
   }
   led_high_count = (uint32_t)high / READLINE_INTERVAL;
   led_low_count = (uint32_t)low / READLINE_INTERVAL;
-  return 0;  
+  return 0;
 }
 
 static int long_key_ref = LUA_NOREF;
 static int short_key_ref = LUA_NOREF;
 
-void default_long_press(void *arg){
-  if(led_high_count == 12 && led_low_count == 12){
+void default_long_press(void *arg) {
+  if (led_high_count == 12 && led_low_count == 12) {
     led_low_count = led_high_count = 6;
   } else {
     led_low_count = led_high_count = 12;
@@ -188,32 +183,32 @@ void default_long_press(void *arg){
   // NODE_DBG("default_long_press is called. hc: %d, lc: %d\n", led_high_count, led_low_count);
 }
 
-void default_short_press(void *arg){
+void default_short_press(void *arg) {
   system_restart();
 }
 
-void key_long_press(void *arg){
+void key_long_press(void *arg) {
   NODE_DBG("key_long_press is called.\n");
-  if(long_key_ref == LUA_NOREF){
+  if (long_key_ref == LUA_NOREF) {
     default_long_press(arg);
     return;
   }
-  if(!gL)
+  if (!gL)
     return;
   lua_rawgeti(gL, LUA_REGISTRYINDEX, long_key_ref);
   lua_call(gL, 0, 0);
 }
 
-void key_short_press(void *arg){
+void key_short_press(void *arg) {
   NODE_DBG("key_short_press is called.\n");
-  if(short_key_ref == LUA_NOREF){
+  if (short_key_ref == LUA_NOREF) {
     default_short_press(arg);
     return;
   }
-  if(!gL)
+  if (!gL)
     return;
   lua_rawgeti(gL, LUA_REGISTRYINDEX, short_key_ref);
-  lua_call(gL, 0, 0);  
+  lua_call(gL, 0, 0);
 }
 
 // Lua: key(type, function)
@@ -221,32 +216,32 @@ static int node_key( lua_State* L )
 {
   int *ref = NULL;
   size_t sl;
-  
+
   const char *str = luaL_checklstring( L, 1, &sl );
   if (str == NULL)
     return luaL_error( L, "wrong arg type" );
 
-  if(sl == 5 && c_strcmp(str, "short") == 0){
+  if (sl == 5 && c_strcmp(str, "short") == 0) {
     ref = &short_key_ref;
-  }else if(sl == 4 && c_strcmp(str, "long") == 0){
+  } else if (sl == 4 && c_strcmp(str, "long") == 0) {
     ref = &long_key_ref;
-  }else{
+  } else {
     ref = &short_key_ref;
   }
   gL = L;
   // luaL_checkanyfunction(L, 2);
-  if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION){
+  if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) {
     lua_pushvalue(L, 2);  // copy argument (func) to the top of stack
-    if(*ref != LUA_NOREF)
+    if (*ref != LUA_NOREF)
       luaL_unref(L, LUA_REGISTRYINDEX, *ref);
     *ref = luaL_ref(L, LUA_REGISTRYINDEX);
   } else {    // unref the key press function
-    if(*ref != LUA_NOREF)
+    if (*ref != LUA_NOREF)
       luaL_unref(L, LUA_REGISTRYINDEX, *ref);
-    *ref = LUA_NOREF; 
+    *ref = LUA_NOREF;
   }
 
-  return 0;  
+  return 0;
 }
 #endif
 
@@ -256,15 +251,15 @@ extern void dojob(lua_Load *load);
 // Lua: input("string")
 static int node_input( lua_State* L )
 {
-  size_t l=0;
+  size_t l = 0;
   const char *s = luaL_checklstring(L, 1, &l);
   if (s != NULL && l > 0 && l < LUA_MAXINPUT - 1)
   {
     lua_Load *load = &gLoad;
-    if(load->line_position == 0){
+    if (load->line_position == 0) {
       c_memcpy(load->line, s, l);
-      load->line[l+1] = '\0';
-      load->line_position = c_strlen(load->line)+1;
+      load->line[l + 1] = '\0';
+      load->line_position = c_strlen(load->line) + 1;
       load->done = 1;
       NODE_DBG("Get command:\n");
       NODE_DBG(load->line); // buggy here
@@ -279,18 +274,18 @@ static int node_input( lua_State* L )
 
 static int output_redir_ref = LUA_NOREF;
 static int serial_debug = 1;
-void output_redirect(const char *str){
+void output_redirect(const char *str) {
   // if(c_strlen(str)>=TX_BUFF_SIZE){
   //   NODE_ERR("output too long.\n");
   //   return;
   // }
 
-  if(output_redir_ref == LUA_NOREF || !gL){
+  if (output_redir_ref == LUA_NOREF || !gL) {
     uart0_sendStr(str);
     return;
   }
 
-  if(serial_debug!=0){
+  if (serial_debug != 0) {
     uart0_sendStr(str);
   }
 
@@ -304,15 +299,15 @@ static int node_output( lua_State* L )
 {
   gL = L;
   // luaL_checkanyfunction(L, 1);
-  if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION){
+  if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION) {
     lua_pushvalue(L, 1);  // copy argument (func) to the top of stack
-    if(output_redir_ref != LUA_NOREF)
+    if (output_redir_ref != LUA_NOREF)
       luaL_unref(L, LUA_REGISTRYINDEX, output_redir_ref);
     output_redir_ref = luaL_ref(L, LUA_REGISTRYINDEX);
   } else {    // unref the key press function
-    if(output_redir_ref != LUA_NOREF)
+    if (output_redir_ref != LUA_NOREF)
       luaL_unref(L, LUA_REGISTRYINDEX, output_redir_ref);
-    output_redir_ref = LUA_NOREF; 
+    output_redir_ref = LUA_NOREF;
     serial_debug = 1;
     return 0;
   }
@@ -320,26 +315,26 @@ static int node_output( lua_State* L )
   if ( lua_isnumber(L, 2) )
   {
     serial_debug = lua_tointeger(L, 2);
-    if(serial_debug!=0)
+    if (serial_debug != 0)
       serial_debug = 1;
   } else {
     serial_debug = 1; // default to 1
   }
 
-  return 0; 
+  return 0;
 }
 
 static int writer(lua_State* L, const void* p, size_t size, void* u)
 {
   UNUSED(L);
   int file_fd = *( (int *)u );
-  if((FS_OPEN_OK - 1)==file_fd)
+  if ((FS_OPEN_OK - 1) == file_fd)
     return 1;
-  NODE_DBG("get fd:%d,size:%d\n",file_fd,size);
-  
-  if(size!=0 && (size!=fs_write(file_fd, (const char *)p, size)) )
+  NODE_DBG("get fd:%d,size:%d\n", file_fd, size);
+
+  if (size != 0 && (size != fs_write(file_fd, (const char *)p, size)) )
     return 1;
-  NODE_DBG("write fd:%d,size:%d\n",file_fd,size);
+  NODE_DBG("write fd:%d,size:%d\n", file_fd, size);
   return 0;
 }
 
@@ -351,45 +346,45 @@ static int node_compile( lua_State* L )
   int file_fd = FS_OPEN_OK - 1;
   size_t len;
   const char *fname = luaL_checklstring( L, 1, &len );
-  if( len > FS_NAME_MAX_LENGTH )
+  if ( len > FS_NAME_MAX_LENGTH )
     return luaL_error(L, "filename too long");
 
   char output[FS_NAME_MAX_LENGTH];
   c_strcpy(output, fname);
   // check here that filename end with ".lua".
-  if(len<4 || (c_strcmp( output+len-4,".lua")!=0) )
+  if (len < 4 || (c_strcmp( output + len - 4, ".lua") != 0) )
     return luaL_error(L, "not a .lua file");
 
-  output[c_strlen(output)-2] = 'c';
-  output[c_strlen(output)-1] = '\0';
+  output[c_strlen(output) - 2] = 'c';
+  output[c_strlen(output) - 1] = '\0';
   NODE_DBG(output);
   NODE_DBG("\n");
-  if (luaL_loadfsfile(L,fname)!=0){
-    return luaL_error(L, lua_tostring(L,-1));
+  if (luaL_loadfsfile(L, fname) != 0) {
+    return luaL_error(L, lua_tostring(L, -1));
   }
 
-  f = toproto(L,-1);
+  f = toproto(L, -1);
 
   int stripping = 1;      /* strip debug information? */
 
   file_fd = fs_open(output, fs_mode2flag("w+"));
-  if(file_fd < FS_OPEN_OK)
+  if (file_fd < FS_OPEN_OK)
   {
     return luaL_error(L, "cannot open/write to file");
   }
 
   lua_lock(L);
-  int result=luaU_dump(L,f,writer,&file_fd,stripping);
+  int result = luaU_dump(L, f, writer, &file_fd, stripping);
   lua_unlock(L);
 
   fs_flush(file_fd);
   fs_close(file_fd);
   file_fd = FS_OPEN_OK - 1;
 
-  if (result==LUA_ERR_CC_INTOVERFLOW){
+  if (result == LUA_ERR_CC_INTOVERFLOW) {
     return luaL_error(L, "value too big or small for target integer type");
   }
-  if (result==LUA_ERR_CC_NOTINTEGER){
+  if (result == LUA_ERR_CC_NOTINTEGER) {
     return luaL_error(L, "target lua_Number is integral but fractional value found");
   }
 
@@ -399,7 +394,7 @@ static int node_compile( lua_State* L )
 // Module function map
 #define MIN_OPT_LEVEL 2
 #include "lrodefs.h"
-const LUA_REG_TYPE node_map[] = 
+const LUA_REG_TYPE node_map[] =
 {
   { LSTRKEY( "restart" ), LFUNCVAL( node_restart ) },
   { LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) },
@@ -416,7 +411,7 @@ const LUA_REG_TYPE node_map[] =
   { LSTRKEY( "output" ), LFUNCVAL( node_output ) },
   { LSTRKEY( "readvdd33" ), LFUNCVAL( node_readvdd33) },
   { LSTRKEY( "compile" ), LFUNCVAL( node_compile) },
-// Combined to dsleep(us, option)  
+// Combined to dsleep(us, option)
 // { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) },
 #if LUA_OPTIMIZE_MEMORY > 0
 

+ 89 - 20
app/platform/flash_api.c

@@ -149,27 +149,21 @@ bool flash_rom_set_size_type(uint8_t size)
     // Dangerous, here are dinosaur infested!!!!!
     // Reboot required!!!
     // If you don't know what you're doing, your nodemcu may turn into stone ...
-#if defined(FLASH_SAFE_API)
-    uint8_t data[SPI_FLASH_SEC_SIZE] ICACHE_STORE_ATTR;
-    flash_safe_read(0, (uint32 *)data, sizeof(data));
-    SPIFlashInfo *p_spi_flash_info = (SPIFlashInfo *)(data);
-    p_spi_flash_info->size = size;
-    flash_safe_erase_sector(0);
-    flash_safe_write(0, (uint32 *)data, sizeof(data));
-    // TODO: CHECKSUM Firmware
-    //p_spi_flash_info = flash_rom_getinfo();
-    //p_spi_flash_info->size = size;
-#else
+    NODE_DBG("\nBEGIN SET FLASH HEADER\n");
     uint8_t data[SPI_FLASH_SEC_SIZE] ICACHE_STORE_ATTR;
-    spi_flash_read(0, (uint32 *)data, sizeof(data));
-    SPIFlashInfo *p_spi_flash_info = (SPIFlashInfo *)(data);
-    p_spi_flash_info->size = size;
-    spi_flash_erase_sector(0);
-    spi_flash_write(0, (uint32 *)data, sizeof(data));
-    // TODO: CHECKSUM Firmware
-    //p_spi_flash_info = flash_rom_getinfo();
-    //p_spi_flash_info->size = size;
-#endif // defined(FLASH_SAFE_API)
+    if (SPI_FLASH_RESULT_OK == spi_flash_read(0, (uint32 *)data, SPI_FLASH_SEC_SIZE))
+    {
+        ((SPIFlashInfo *)(&data[0]))->size = size;
+        if (SPI_FLASH_RESULT_OK == spi_flash_erase_sector(0 * SPI_FLASH_SEC_SIZE))
+        {
+            NODE_DBG("\nERASE SUCCESS\n");
+        }
+        if (SPI_FLASH_RESULT_OK == spi_flash_write(0, (uint32 *)data, SPI_FLASH_SEC_SIZE))
+        {
+            NODE_DBG("\nWRITE SUCCESS, %u\n", size);
+        }
+    }
+    NODE_DBG("\nEND SET FLASH HEADER\n");
     return true;
 }
 
@@ -207,6 +201,16 @@ bool flash_rom_set_size_byte(uint32_t size)
         flash_size = SIZE_32MBIT;
         flash_rom_set_size_type(flash_size);
         break;
+    case 8 * 1024 * 1024:
+        // 64Mbit, 8MByte
+        flash_size = SIZE_64MBIT;
+        flash_rom_set_size_type(flash_size);
+        break;
+    case 16 * 1024 * 1024:
+        // 128Mbit, 16MByte
+        flash_size = SIZE_128MBIT;
+        flash_rom_set_size_type(flash_size);
+        break;
     default:
         // Unknown flash size.
         result = false;
@@ -272,6 +276,46 @@ uint32_t flash_rom_get_speed(void)
     return speed;
 }
 
+bool flash_rom_set_speed(uint32_t speed)
+{
+    // Dangerous, here are dinosaur infested!!!!!
+    // Reboot required!!!
+    // If you don't know what you're doing, your nodemcu may turn into stone ...
+    NODE_DBG("\nBEGIN SET FLASH HEADER\n");
+    uint8_t data[SPI_FLASH_SEC_SIZE] ICACHE_STORE_ATTR;
+    uint8_t speed_type = SPEED_40MHZ;
+    if (speed < 26700000)
+    {
+        speed_type = SPEED_20MHZ;
+    }
+    else if (speed < 40000000)
+    {
+        speed_type = SPEED_26MHZ;
+    }
+    else if (speed < 80000000)
+    {
+        speed_type = SPEED_40MHZ;
+    }
+    else if (speed >= 80000000)
+    {
+        speed_type = SPEED_80MHZ;
+    }
+    if (SPI_FLASH_RESULT_OK == spi_flash_read(0, (uint32 *)data, SPI_FLASH_SEC_SIZE))
+    {
+        ((SPIFlashInfo *)(&data[0]))->speed = speed_type;
+        if (SPI_FLASH_RESULT_OK == spi_flash_erase_sector(0 * SPI_FLASH_SEC_SIZE))
+        {
+            NODE_DBG("\nERASE SUCCESS\n");
+        }
+        if (SPI_FLASH_RESULT_OK == spi_flash_write(0, (uint32 *)data, SPI_FLASH_SEC_SIZE))
+        {
+            NODE_DBG("\nWRITE SUCCESS, %u\n", speed_type);
+        }
+    }
+    NODE_DBG("\nEND SET FLASH HEADER\n");
+    return true;
+}
+
 bool flash_init_data_written(void)
 {
     // FLASH SEC - 4
@@ -356,3 +400,28 @@ uint8_t byte_of_aligned_array(const uint8_t *aligned_array, uint32_t index)
     uint8_t *p = (uint8_t *) (&v);
     return p[ (index % 4) ];
 }
+
+// uint8_t flash_rom_get_checksum(void)
+// {
+//     // SPIFlashInfo spi_flash_info ICACHE_STORE_ATTR = flash_rom_getinfo();
+//     // uint32_t address = sizeof(spi_flash_info) + spi_flash_info.segment_size;
+//     // uint32_t address_aligned_4bytes = (address + 3) & 0xFFFFFFFC;
+//     // uint8_t buffer[64] = {0};
+//     // spi_flash_read(address, (uint32 *) buffer, 64);
+//     // uint8_t i = 0;
+//     // c_printf("\nBEGIN DUMP\n");
+//     // for (i = 0; i < 64; i++)
+//     // {
+//     //     c_printf("%02x," , buffer[i]);
+//     // }
+//     // i = (address + 0x10) & 0x10 - 1;
+//     // c_printf("\nSIZE:%d CHECK SUM:%02x\n", spi_flash_info.segment_size, buffer[i]);
+//     // c_printf("\nEND DUMP\n");
+//     // return buffer[0];
+//     return 0;
+// }
+
+// uint8_t flash_rom_calc_checksum(void)
+// {
+//     return 0;
+// }

+ 9 - 4
app/platform/flash_api.h

@@ -16,10 +16,10 @@
 
 #define FLASH_SIZE_256KBYTE (FLASH_SIZE_2MBIT  / 8)
 #define FLASH_SIZE_512KBYTE (FLASH_SIZE_4MBIT  / 8)
-#define FLASH_SIZE_1MBYTE   (FLASH_SIZE_8MBIT  / 8) 
+#define FLASH_SIZE_1MBYTE   (FLASH_SIZE_8MBIT  / 8)
 #define FLASH_SIZE_2MBYTE   (FLASH_SIZE_16MBIT / 8)
 #define FLASH_SIZE_4MBYTE   (FLASH_SIZE_32MBIT / 8)
-#define FLASH_SIZE_8MBYTE   (FLASH_SIZE_64MBIT / 8) 
+#define FLASH_SIZE_8MBYTE   (FLASH_SIZE_64MBIT / 8)
 #define FLASH_SIZE_16MBYTE  (FLASH_SIZE_128MBIT/ 8)
 
 #define FLASH_SAFEMODE_ENTER() \
@@ -57,8 +57,8 @@ do { \
 
 typedef struct
 {
-    uint8_t magic_e9;
-    uint8_t segments;
+    uint8_t header_magic;
+    uint8_t segment_count;
     enum
     {
         MODE_QIO = 0,
@@ -83,6 +83,9 @@ typedef struct
         SIZE_64MBIT = 5,
         SIZE_128MBIT = 6,
     } size : 4;
+    uint32_t entry_point;
+    uint32_t memory_offset;
+    uint32_t segment_size; 
 } ICACHE_STORE_TYPEDEF_ATTR SPIFlashInfo;
 
 uint32_t flash_detect_size_byte(void);
@@ -104,5 +107,7 @@ 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);
+// uint8_t flash_rom_get_checksum(void);
+// uint8_t flash_rom_calc_checksum(void);
 
 #endif // __FLASH_API_H__

+ 13 - 1
app/user/user_main.c

@@ -60,7 +60,19 @@ void nodemcu_init(void)
         NODE_DBG("Can not init platform for modules.\n");
         return;
     }
-    
+
+#if defined(FLASH_SAFE_API)
+    if( flash_safe_get_size_byte() != flash_rom_get_size_byte()) {
+        NODE_ERR("Self adjust flash size.\n");
+        // Fit hardware real flash size.
+        flash_rom_set_size_byte(flash_safe_get_size_byte());
+        // Flash init data at FLASHSIZE - 0x04000 Byte.
+        flash_init_data_default();
+        // Flash blank data at FLASHSIZE - 0x02000 Byte.
+        flash_init_data_blank();        
+    }
+#endif // defined(FLASH_SAFE_API)
+
     if( !flash_init_data_written() ){
         NODE_ERR("Restore init data.\n");
         // Flash init data at FLASHSIZE - 0x04000 Byte.