Browse Source

Try to fix flash auto detection bug.

HuangRui 9 years ago
parent
commit
ed87cbd96f
4 changed files with 148 additions and 55 deletions
  1. 4 4
      app/modules/node.c
  2. 4 4
      app/platform/cpu_esp8266.h
  3. 91 31
      app/platform/flash_api.c
  4. 49 16
      app/platform/flash_api.h

+ 4 - 4
app/modules/node.c

@@ -80,9 +80,9 @@ static int node_info( lua_State* L )
   lua_pushinteger(L, NODE_VERSION_REVISION);
   lua_pushinteger(L, NODE_VERSION_REVISION);
   lua_pushinteger(L, system_get_chip_id());   // chip id
   lua_pushinteger(L, system_get_chip_id());   // chip id
   lua_pushinteger(L, spi_flash_get_id());     // flash id
   lua_pushinteger(L, spi_flash_get_id());     // flash id
-  lua_pushinteger(L, flash_get_size_byte() / 1024);  // flash size in KB
-  lua_pushinteger(L, flash_get_mode());
-  lua_pushinteger(L, flash_get_speed());
+  lua_pushinteger(L, flash_detect_size_byte() / 1024);  // flash size in KB
+  lua_pushinteger(L, flash_rom_get_mode());
+  lua_pushinteger(L, flash_rom_get_speed());
   return 8;  
   return 8;  
 }
 }
 
 
@@ -121,7 +121,7 @@ static int node_flashsize( lua_State* L )
   //    flash_set_size_byte(sz);
   //    flash_set_size_byte(sz);
   //  }
   //  }
   //}
   //}
-  uint32_t sz = flash_get_size_byte();
+  uint32_t sz = flash_detect_size_byte();
   lua_pushinteger( L, sz );
   lua_pushinteger( L, sz );
   return 1;  
   return 1;  
 }
 }

+ 4 - 4
app/platform/cpu_esp8266.h

@@ -30,7 +30,7 @@
 #elif defined(FLASH_16M)
 #elif defined(FLASH_16M)
 #define FLASH_SEC_NUM 	0x1000
 #define FLASH_SEC_NUM 	0x1000
 #elif defined(FLASH_AUTOSIZE)
 #elif defined(FLASH_AUTOSIZE)
-#define FLASH_SEC_NUM 	(flash_get_sec_num())
+#define FLASH_SEC_NUM 	(flash_rom_get_sec_num())
 #else
 #else
 #define FLASH_SEC_NUM 	0x80
 #define FLASH_SEC_NUM 	0x80
 #endif
 #endif
@@ -54,8 +54,8 @@
 // SpiFlashOpResult spi_flash_erase_sector(uint16 sec);
 // SpiFlashOpResult spi_flash_erase_sector(uint16 sec);
 // SpiFlashOpResult spi_flash_write(uint32 des_addr, uint32 *src_addr, uint32 size);
 // SpiFlashOpResult spi_flash_write(uint32 des_addr, uint32 *src_addr, uint32 size);
 // SpiFlashOpResult spi_flash_read(uint32 src_addr, uint32 *des_addr, uint32 size);
 // SpiFlashOpResult spi_flash_read(uint32 src_addr, uint32 *des_addr, uint32 size);
-#define flash_write spi_flash_write
-#define flash_erase spi_flash_erase_sector
-#define flash_read spi_flash_read
+#define flash_write flash_safe_write
+#define flash_erase flash_safe_erase_sector
+#define flash_read flash_safe_read
 
 
 #endif // #ifndef __CPU_ESP8266_H__
 #endif // #ifndef __CPU_ESP8266_H__

+ 91 - 31
app/platform/flash_api.c

@@ -20,23 +20,83 @@ static volatile const uint8_t flash_init_data[128] ICACHE_STORE_ATTR ICACHE_RODA
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 };
 
 
-SPIFlashInfo flash_get_info(void)
+uint32_t flash_detect_size_byte(void)
+{
+    uint32_t dummy_size = FLASH_SIZE_256KBYTE;
+    uint8_t data_orig[64] ICACHE_STORE_ATTR = {0};
+    uint8_t data_new[64] ICACHE_STORE_ATTR = {0};
+    if (SPI_FLASH_RESULT_OK == flash_safe_read(0, (uint32 *)data_orig, 64))
+    {
+        dummy_size = FLASH_SIZE_256KBYTE;
+        while ((dummy_size < FLASH_SIZE_16MBYTE) &&
+                (SPI_FLASH_RESULT_OK == flash_safe_read(dummy_size, (uint32 *)data_new, 64)))
+        {
+            dummy_size *= 2;
+        }
+    };
+    return dummy_size;
+}
+
+uint32_t flash_safe_get_size_byte(void)
+{
+    static uint32_t flash_size = 0;
+    if (flash_size == 0)
+    {
+        flash_size = flash_detect_size_byte();
+    }
+    return flash_size;
+}
+
+uint16_t flash_safe_get_sec_num(void)
+{
+    return (flash_safe_get_size_byte() / (SPI_FLASH_SEC_SIZE));
+}
+
+SpiFlashOpResult flash_safe_read(uint32 src_addr, uint32 *des_addr, uint32 size)
+{
+    SpiFlashOpResult result = SPI_FLASH_RESULT_ERR;
+    FLASH_SAFEMODE_ENTER();
+    result = spi_flash_read(src_addr, (uint32 *) des_addr, size);
+    FLASH_SAFEMODE_LEAVE();
+    return result;
+}
+
+SpiFlashOpResult flash_safe_write(uint32 des_addr, uint32 *src_addr, uint32 size)
+{
+    SpiFlashOpResult result = SPI_FLASH_RESULT_ERR;
+    FLASH_SAFEMODE_ENTER();
+    result = spi_flash_write(des_addr, src_addr, size);
+    FLASH_SAFEMODE_LEAVE();
+    return result;
+}
+
+SpiFlashOpResult flash_safe_erase_sector(uint16 sec)
+{
+    SpiFlashOpResult result = SPI_FLASH_RESULT_ERR;
+    FLASH_SAFEMODE_ENTER();
+    result = spi_flash_erase_sector(sec);
+    FLASH_SAFEMODE_LEAVE();
+    return result;
+}
+
+SPIFlashInfo flash_rom_getinfo(void)
 {
 {
     volatile SPIFlashInfo spi_flash_info ICACHE_STORE_ATTR;
     volatile SPIFlashInfo spi_flash_info ICACHE_STORE_ATTR;
-    spi_flash_info = *((SPIFlashInfo *)(FLASH_MAP_START_ADDRESS));
-    // spi_flash_read(0, (uint32 *)(& spi_flash_info), sizeof(spi_flash_info));
+    // Don't use it before cache read disabled
+    // spi_flash_info = *((SPIFlashInfo *)(FLASH_ADDRESS_START_MAP));
+    flash_safe_read(0, (uint32 *)(& spi_flash_info), sizeof(spi_flash_info));
     return spi_flash_info;
     return spi_flash_info;
 }
 }
 
 
-uint8_t flash_get_size(void)
+uint8_t flash_rom_get_size_type(void)
 {
 {
-    return flash_get_info().size;
+    return flash_rom_getinfo().size;
 }
 }
 
 
-uint32_t flash_get_size_byte(void)
+uint32_t flash_rom_get_size_byte(void)
 {
 {
     uint32_t flash_size = 0;
     uint32_t flash_size = 0;
-    switch (flash_get_info().size)
+    switch (flash_rom_getinfo().size)
     {
     {
     case SIZE_2MBIT:
     case SIZE_2MBIT:
         // 2Mbit, 256kByte
         // 2Mbit, 256kByte
@@ -74,23 +134,23 @@ uint32_t flash_get_size_byte(void)
     return flash_size;
     return flash_size;
 }
 }
 
 
-bool flash_set_size(uint8_t size)
+bool flash_rom_set_size_type(uint8_t size)
 {
 {
     // Dangerous, here are dinosaur infested!!!!!
     // Dangerous, here are dinosaur infested!!!!!
     // Reboot required!!!
     // Reboot required!!!
     // If you don't know what you're doing, your nodemcu may turn into stone ...
     // 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;
     uint8_t data[SPI_FLASH_SEC_SIZE] ICACHE_STORE_ATTR;
-    spi_flash_read(0, (uint32 *)data, sizeof(data));
+    flash_safe_read(0, (uint32 *)data, sizeof(data));
     SPIFlashInfo *p_spi_flash_info = (SPIFlashInfo *)(data);
     SPIFlashInfo *p_spi_flash_info = (SPIFlashInfo *)(data);
     p_spi_flash_info->size = size;
     p_spi_flash_info->size = size;
-    spi_flash_erase_sector(0);
-    spi_flash_write(0, (uint32 *)data, sizeof(data));
-    //p_spi_flash_info = flash_get_info();
+    flash_safe_erase_sector(0);
+    flash_safe_write(0, (uint32 *)data, sizeof(data));
+    //p_spi_flash_info = flash_rom_getinfo();
     //p_spi_flash_info->size = size;
     //p_spi_flash_info->size = size;
     return true;
     return true;
 }
 }
 
 
-bool flash_set_size_byte(uint32_t size)
+bool flash_rom_set_size_byte(uint32_t size)
 {
 {
     // Dangerous, here are dinosaur infested!!!!!
     // Dangerous, here are dinosaur infested!!!!!
     // Reboot required!!!
     // Reboot required!!!
@@ -102,27 +162,27 @@ bool flash_set_size_byte(uint32_t size)
     case 256 * 1024:
     case 256 * 1024:
         // 2Mbit, 256kByte
         // 2Mbit, 256kByte
         flash_size = SIZE_2MBIT;
         flash_size = SIZE_2MBIT;
-        flash_set_size(flash_size);
+        flash_rom_set_size_type(flash_size);
         break;
         break;
     case 512 * 1024:
     case 512 * 1024:
         // 4Mbit, 512kByte
         // 4Mbit, 512kByte
         flash_size = SIZE_4MBIT;
         flash_size = SIZE_4MBIT;
-        flash_set_size(flash_size);
+        flash_rom_set_size_type(flash_size);
         break;
         break;
     case 1 * 1024 * 1024:
     case 1 * 1024 * 1024:
         // 8Mbit, 1MByte
         // 8Mbit, 1MByte
         flash_size = SIZE_8MBIT;
         flash_size = SIZE_8MBIT;
-        flash_set_size(flash_size);
+        flash_rom_set_size_type(flash_size);
         break;
         break;
     case 2 * 1024 * 1024:
     case 2 * 1024 * 1024:
         // 16Mbit, 2MByte
         // 16Mbit, 2MByte
         flash_size = SIZE_16MBIT;
         flash_size = SIZE_16MBIT;
-        flash_set_size(flash_size);
+        flash_rom_set_size_type(flash_size);
         break;
         break;
     case 4 * 1024 * 1024:
     case 4 * 1024 * 1024:
         // 32Mbit, 4MByte
         // 32Mbit, 4MByte
         flash_size = SIZE_32MBIT;
         flash_size = SIZE_32MBIT;
-        flash_set_size(flash_size);
+        flash_rom_set_size_type(flash_size);
         break;
         break;
     default:
     default:
         // Unknown flash size.
         // Unknown flash size.
@@ -132,22 +192,22 @@ bool flash_set_size_byte(uint32_t size)
     return result;
     return result;
 }
 }
 
 
-uint16_t flash_get_sec_num(void)
+uint16_t flash_rom_get_sec_num(void)
 {
 {
     //static uint16_t sec_num = 0;
     //static uint16_t sec_num = 0;
-    // return flash_get_size_byte() / (SPI_FLASH_SEC_SIZE);
-    // c_printf("\nflash_get_size_byte()=%d\n", ( flash_get_size_byte() / (SPI_FLASH_SEC_SIZE) ));
+    // return flash_rom_get_size_byte() / (SPI_FLASH_SEC_SIZE);
+    // c_printf("\nflash_rom_get_size_byte()=%d\n", ( flash_rom_get_size_byte() / (SPI_FLASH_SEC_SIZE) ));
     // if( sec_num == 0 )
     // if( sec_num == 0 )
     //{
     //{
     //    sec_num = 4 * 1024 * 1024 / (SPI_FLASH_SEC_SIZE);
     //    sec_num = 4 * 1024 * 1024 / (SPI_FLASH_SEC_SIZE);
     //}
     //}
     //return sec_num;
     //return sec_num;
-    return ( flash_get_size_byte() / (SPI_FLASH_SEC_SIZE) );
+    return ( flash_rom_get_size_byte() / (SPI_FLASH_SEC_SIZE) );
 }
 }
 
 
-uint8_t flash_get_mode(void)
+uint8_t flash_rom_get_mode(void)
 {
 {
-    SPIFlashInfo spi_flash_info = flash_get_info();
+    SPIFlashInfo spi_flash_info = flash_rom_getinfo();
     switch (spi_flash_info.mode)
     switch (spi_flash_info.mode)
     {
     {
     // Reserved for future use
     // Reserved for future use
@@ -163,10 +223,10 @@ uint8_t flash_get_mode(void)
     return spi_flash_info.mode;
     return spi_flash_info.mode;
 }
 }
 
 
-uint32_t flash_get_speed(void)
+uint32_t flash_rom_get_speed(void)
 {
 {
     uint32_t speed = 0;
     uint32_t speed = 0;
-    SPIFlashInfo spi_flash_info = flash_get_info();
+    SPIFlashInfo spi_flash_info = flash_rom_getinfo();
     switch (spi_flash_info.speed)
     switch (spi_flash_info.speed)
     {
     {
     case SPEED_40MHZ:
     case SPEED_40MHZ:
@@ -193,7 +253,7 @@ bool flash_init_data_written(void)
 {
 {
     // FLASH SEC - 4
     // FLASH SEC - 4
     uint32_t data[2] ICACHE_STORE_ATTR;
     uint32_t data[2] ICACHE_STORE_ATTR;
-    if (SPI_FLASH_RESULT_OK == spi_flash_read((flash_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)data, sizeof(data)))
+    if (SPI_FLASH_RESULT_OK == flash_safe_read((flash_rom_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)data, sizeof(data)))
     {
     {
         if (data[0] == 0xFFFFFFFF && data[1] == 0xFFFFFFFF)
         if (data[0] == 0xFFFFFFFF && data[1] == 0xFFFFFFFF)
         {
         {
@@ -210,9 +270,9 @@ bool flash_init_data_default(void)
     // Reboot required!!!
     // Reboot required!!!
     // It will init system data to default!
     // It will init system data to default!
     bool result = false;
     bool result = false;
-    if (SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_get_sec_num() - 4)))
+    if (SPI_FLASH_RESULT_OK == flash_safe_erase_sector((flash_rom_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))
+        if (SPI_FLASH_RESULT_OK == flash_safe_write((flash_rom_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)flash_init_data, 128))
         {
         {
             result = true;
             result = true;
         }
         }
@@ -227,8 +287,8 @@ bool flash_init_data_blank(void)
     // Reboot required!!!
     // Reboot required!!!
     // It will init system config to blank!
     // It will init system config to blank!
     bool result = false;
     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))))
+    if ((SPI_FLASH_RESULT_OK == flash_safe_erase_sector((flash_rom_get_sec_num() - 2))) &&
+            (SPI_FLASH_RESULT_OK == flash_safe_erase_sector((flash_rom_get_sec_num() - 1))))
     {
     {
         result = true;
         result = true;
     }
     }

+ 49 - 16
app/platform/flash_api.h

@@ -4,28 +4,55 @@
 #include "user_config.h"
 #include "user_config.h"
 #include "cpu_esp8266.h"
 #include "cpu_esp8266.h"
 
 
-#define FLASH_MAP_START_ADDRESS (INTERNAL_FLASH_START_ADDRESS)
+#define FLASH_ADDRESS_START_MAP (INTERNAL_FLASH_START_ADDRESS)
+
+#define FLASH_SIZE_2MBIT    (2   * 1024 * 1024)
+#define FLASH_SIZE_4MBIT    (4   * 1024 * 1024)
+#define FLASH_SIZE_8MBIT    (8   * 1024 * 1024)
+#define FLASH_SIZE_16MBIT   (16  * 1024 * 1024)
+#define FLASH_SIZE_32MBIT   (32  * 1024 * 1024)
+#define FLASH_SIZE_64MBIT   (64  * 1024 * 1024)
+#define FLASH_SIZE_128MBIT  (128 * 1024 * 1024)
+
+#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_2MBYTE   (FLASH_SIZE_16MBIT / 8)
+#define FLASH_SIZE_4MBYTE   (FLASH_SIZE_32MBIT / 8)
+#define FLASH_SIZE_8MBYTE   (FLASH_SIZE_64MBIT / 8) 
+#define FLASH_SIZE_16MBYTE  (FLASH_SIZE_128MBIT/ 8)
+
+#define FLASH_SAFEMODE_ENTER() \
+do { \
+    extern SpiFlashChip * flashchip; \
+    flashchip->chip_size = FLASH_SIZE_256KBYTE
+
+
+#define FLASH_SAFEMODE_LEAVE() \
+    flashchip->chip_size = FLASH_SIZE_16MBYTE; \
+} while(0)
 
 
 /******************************************************************************
 /******************************************************************************
  * ROM Function definition
  * ROM Function definition
  * Note: It is unsafe to use ROM function, but it may efficient.
  * Note: It is unsafe to use ROM function, but it may efficient.
  * SPIEraseSector
  * SPIEraseSector
- * unknown SPIEraseSector(uint16 sec);
+ * SpiFlashOpResult  SPIEraseSector(uint16 sec);
  * The 1st parameter is flash sector number.
  * The 1st parameter is flash sector number.
+ * Note: Must disable cache read before using it.
 
 
- * SPIRead (Unsafe)
- * unknown SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
+ * SPIRead
+ * SpiFlashOpResult  SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
  * The 1st parameter is source addresses.
  * The 1st parameter is source addresses.
  * The 2nd parameter is destination addresses.
  * The 2nd parameter is destination addresses.
  * The 3rd parameter is size.
  * 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.
+ * Note: Must disable cache read before using it.
 
 
- * SPIWrite (Unsafe)
- * unknown SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
+ * SPIWrite
+ * SpiFlashOpResult  SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
  * The 1st parameter is destination addresses.
  * The 1st parameter is destination addresses.
  * The 2nd parameter is source addresses.
  * The 2nd parameter is source addresses.
  * The 3rd parameter is size.
  * 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.
+ * Note: Must disable cache read before using it.
 *******************************************************************************/
 *******************************************************************************/
 
 
 typedef struct
 typedef struct
@@ -58,14 +85,20 @@ typedef struct
     } size : 4;
     } size : 4;
 } ICACHE_STORE_TYPEDEF_ATTR SPIFlashInfo;
 } ICACHE_STORE_TYPEDEF_ATTR SPIFlashInfo;
 
 
-SPIFlashInfo flash_get_info(void);
-uint8_t flash_get_size(void);
-uint32_t flash_get_size_byte(void);
-bool flash_set_size(uint8_t);
-bool flash_set_size_byte(uint32_t);
-uint16_t flash_get_sec_num(void);
-uint8_t flash_get_mode(void);
-uint32_t flash_get_speed(void);
+uint32_t flash_detect_size_byte(void);
+uint32_t flash_safe_get_size_byte(void);
+uint16_t flash_safe_get_sec_num(void);
+SpiFlashOpResult flash_safe_read(uint32 src_addr, uint32 *des_addr, uint32 size);
+SpiFlashOpResult flash_safe_write(uint32 des_addr, uint32 *src_addr, uint32 size);
+SpiFlashOpResult flash_safe_erase_sector(uint16 sec);
+SPIFlashInfo flash_rom_getinfo(void);
+uint8_t flash_rom_get_size_type(void);
+uint32_t flash_rom_get_size_byte(void);
+bool flash_rom_set_size_type(uint8_t);
+bool flash_rom_set_size_byte(uint32_t);
+uint16_t flash_rom_get_sec_num(void);
+uint8_t flash_rom_get_mode(void);
+uint32_t flash_rom_get_speed(void);
 bool flash_init_data_written(void);
 bool flash_init_data_written(void);
 bool flash_init_data_default(void);
 bool flash_init_data_default(void);
 bool flash_init_data_blank(void);
 bool flash_init_data_blank(void);