From 715ff5b7aaeaef48da27ef4bc0af8630d970400a Mon Sep 17 00:00:00 2001
From: HuangRui <vowstar@gmail.com>
Date: Wed, 31 Dec 2014 02:47:44 +0800
Subject: [PATCH] NodeMCU firmware can auto detect flash size now.

---
 app/include/user_config.h  |  3 +-
 app/platform/cpu_esp8266.h |  3 ++
 app/platform/flash_api.c   | 71 ++++++++++++++++++++++++++++++++++++++
 app/platform/flash_api.h   | 34 ++++++++++++++++++
 app/user/user_main.c       |  4 ++-
 5 files changed, 113 insertions(+), 2 deletions(-)
 create mode 100644 app/platform/flash_api.c
 create mode 100644 app/platform/flash_api.h

diff --git a/app/include/user_config.h b/app/include/user_config.h
index 8a74351b..a9c75301 100644
--- a/app/include/user_config.h
+++ b/app/include/user_config.h
@@ -3,10 +3,11 @@
 
 #define NODE_VERSION	"NodeMcu 0.9.4"
 #define BUILD_DATE	"build 20141230"
-#define FLASH_512K
+// #define FLASH_512K
 // #define FLASH_1M
 // #define FLASH_2M
 // #define FLASH_4M
+#define FLASH_AUTOSIZE
 // #define DEVELOP_VERSION
 #define FULL_VERSION_FOR_USER
 
diff --git a/app/platform/cpu_esp8266.h b/app/platform/cpu_esp8266.h
index ecccee93..46689510 100644
--- a/app/platform/cpu_esp8266.h
+++ b/app/platform/cpu_esp8266.h
@@ -5,6 +5,7 @@
 #include "spi_flash.h"
 #include "pin_map.h"
 #include "user_config.h"
+#include "flash_api.h"
 // Number of resources (0 if not available/not implemented)
 #define NUM_GPIO              GPIO_PIN_NUM
 #define NUM_SPI               1
@@ -24,6 +25,8 @@
 #define FLASH_SEC_NUM 	0x200
 #elif defined(FLASH_4M)
 #define FLASH_SEC_NUM 	0x400
+#elif defined(FLASH_AUTOSIZE)
+#define FLASH_SEC_NUM 	(flash_get_sec_num())
 #else
 #define FLASH_SEC_NUM 	0x80
 #endif
diff --git a/app/platform/flash_api.c b/app/platform/flash_api.c
new file mode 100644
index 00000000..05afd9ac
--- /dev/null
+++ b/app/platform/flash_api.c
@@ -0,0 +1,71 @@
+/******************************************************************************
+ * Flash api for NodeMCU
+*******************************************************************************/
+#include "user_config.h"
+#include "flash_api.h"
+#include "spi_flash.h"
+
+SPIFlashInfo *ICACHE_FLASH_ATTR
+flash_get_info()
+{
+    static SPIFlashInfo spi_flash_info;
+    static bool is_spi_flash_info_initialized = false;
+    // Make the code more fast
+    if (!is_spi_flash_info_initialized)
+    {
+        SPIRead(0, &spi_flash_info, sizeof(spi_flash_info));
+        is_spi_flash_info_initialized = true;
+    }
+    return &spi_flash_info;
+}
+
+uint32_t ICACHE_FLASH_ATTR
+flash_get_size_byte()
+{
+    static uint32_t flash_size = 0;
+    // Make the code more fast
+    if (flash_size == 0 )
+    {
+        SPIFlashInfo *p_spi_flash_info = flash_get_info();
+        switch (p_spi_flash_info->size)
+        {
+        case SIZE_2MBIT:
+            // 2Mbit, 256kByte
+            flash_size = 256 * 1024;
+            break;
+        case SIZE_4MBIT:
+            // 4Mbit, 512kByte
+            flash_size = 512 * 1024;
+            break;
+        case SIZE_8MBIT:
+            // 8Mbit, 1MByte
+            flash_size = 1 * 1024 * 1024;
+            break;
+        case SIZE_16MBIT:
+            // 16Mbit, 2MByte
+            flash_size = 2 * 1024 * 1024;
+            break;
+        case SIZE_32MBIT:
+            // 32Mbit, 4MByte
+            flash_size = 4 * 1024 * 1024;
+            break;
+        default:
+            // Unknown flash size, fall back mode.
+            flash_size = 512 * 1024;
+            break;
+        }
+    }
+    return flash_size;
+}
+
+uint16_t ICACHE_FLASH_ATTR
+flash_get_sec_num()
+{
+    static uint16_t result = 0;
+    // Make the code more fast
+    if (result == 0 )
+    {
+        result = flash_get_size_byte() / SPI_FLASH_SEC_SIZE;
+    }
+    return result;
+}
\ No newline at end of file
diff --git a/app/platform/flash_api.h b/app/platform/flash_api.h
new file mode 100644
index 00000000..8ff2b455
--- /dev/null
+++ b/app/platform/flash_api.h
@@ -0,0 +1,34 @@
+#ifndef __FLASH_API_H__
+#define __FLASH_API_H__
+#include "ets_sys.h"
+typedef struct __attribute__((packed))
+{
+    uint8_t unknown0;
+    uint8_t unknown1;
+    enum
+    {
+        MODE_QIO = 0,
+        MODE_QOUT = 1,
+        MODE_DIO = 2,
+        MODE_DOUT = 15,
+    } mode : 8;
+    enum
+    {
+        SPEED_40MHZ = 0,
+        SPEED_26MHZ = 1,
+        SPEED_20MHZ = 2,
+        SPEED_80MHZ = 15,
+    } speed : 4;
+    enum
+    {
+        SIZE_4MBIT = 0,
+        SIZE_2MBIT = 1,
+        SIZE_8MBIT = 2,
+        SIZE_16MBIT = 3,
+        SIZE_32MBIT = 4,
+    } size : 4;
+} SPIFlashInfo;
+
+uint32_t flash_get_size_byte();
+uint16_t flash_get_sec_num();
+#endif // __FLASH_API_H__
diff --git a/app/user/user_main.c b/app/user/user_main.c
index 13e727bf..c6ea7d84 100644
--- a/app/user/user_main.c
+++ b/app/user/user_main.c
@@ -48,6 +48,8 @@ extern void spiffs_mount();
 // extern void test_spiffs();
 // extern int test_romfs();
 
+// extern uint16_t flash_get_sec_num();
+
 /******************************************************************************
  * FunctionName : user_init
  * Description  : entry of user application, init user function here
@@ -104,7 +106,7 @@ void user_init(void)
     // lua_main( 2, lua_argv );
     // char* lua_argv[] = { (char *)"lua", (char *)"-e", (char *)"pwm.setup(0,100,50) pwm.start(0) pwm.stop(0)", NULL };
     // lua_main( 3, lua_argv );
-    
+    // NODE_DBG("Flash sec num: 0x%x\n", flash_get_sec_num());
     task_init();
     system_os_post(USER_TASK_PRIO_0,SIG_LUA,'s');
 }