Using > 32Mb (>4MB) flash

piersfinlayson
Posts: 5
Joined: Tue Mar 08, 2016 1:03 am

Using > 32Mb (>4MB) flash

Postby piersfinlayson » Wed Oct 12, 2016 4:03 am

Hi,

Is it possible to access > 4MB flash via the non OS SDK?

I've written a test application and can't access flash memory above 0x400000 (sector 0x400) using spi_flash_erase_sector. I have tried with all of the various flash_size_map settings in gen_appbin.py plus some other values, so am guessing the SDK doesn't support > 4MB access.

Thanks,
Piers

ESP_Greg

Re: Using > 32Mb (>4MB) flash

Postby ESP_Greg » Wed Oct 12, 2016 6:16 pm

Hi, we have a demo on RTOS SDK. You can refer to below code, and porting to non-RTOS SDK. It will work.

user_rw_flash_16Mbyte_rtos.c

Code: Select all

#include "esp_common.h"
#include "c_types.h"
#include "spi_flash.h"

extern SpiFlashChip  flashchip;

#define USER_FLASH_SIZE_BYTE (16*1024*1024)
SpiFlashOpResult user_flash_erase_sector(uint16 sector)
{
    uint32 chipsize = flashchip.chip_size; // backup org chip size
     flashchip.chip_size=USER_FLASH_SIZE_BYTE;
    uint8 status=0;
    status=spi_flash_erase_sector(sector);
   flashchip.chip_size = chipsize; // restore chip size
    return status;
}
SpiFlashOpResult user_flash_write(uint32 des_addr, uint32 *src_addr, uint32 size)
{
    uint32 chipsize = flashchip.chip_size; // backup org chip size
     flashchip.chip_size=USER_FLASH_SIZE_BYTE;
    uint8 status=0;
    status=spi_flash_write(des_addr,src_addr,size);
   flashchip.chip_size = chipsize; // restore chip size
    return status;
}
SpiFlashOpResult user_flash_read(uint32 src_addr, uint32 *des_addr, uint32 size)
{
    uint32 chipsize = flashchip.chip_size; // backup org chip size
     flashchip.chip_size=USER_FLASH_SIZE_BYTE;
    uint8 status=0;
    status=spi_flash_read(src_addr,des_addr,size);
   flashchip.chip_size = chipsize; // restore chip size
    return status;
}



//========================================================
SpiFlashOpResult IRAM_ATTR SPI_block_erase_t(SpiFlashChip * spi, uint32 addr)
{
   Wait_SPI_Idle(spi);

  // sector erase  4Kbytes erase is sector erase.
  WRITE_PERI_REG(0x60000204, addr & 0xffffff);
  WRITE_PERI_REG(0x60000200, BIT23);
  while(READ_PERI_REG(0x60000200)!=0);
  Wait_SPI_Idle(spi);

  return SPI_FLASH_RESULT_OK;
}



SpiFlashOpResult IRAM_ATTR flash_erase_block(uint32 block_num)
{
    //disable icache
    Cache_Read_Disable();
    //wait spi idle
    Wait_SPI_Idle(&flashchip);

    if (block_num>= ((flashchip.chip_size)/(flashchip.block_size)))
       {   return SPI_FLASH_RESULT_ERR;
       }

   if ( SPI_FLASH_RESULT_OK != SPI_write_enable(&flashchip))
       {   return SPI_FLASH_RESULT_ERR;
       }

   if (SPI_FLASH_RESULT_OK != SPI_block_erase_t(&flashchip, block_num*(flashchip.block_size)))
   {     return SPI_FLASH_RESULT_ERR;
   }

   
    Wait_SPI_Idle(&flashchip);
    //enable icache
    Cache_Read_Enable_New();
    return SPI_FLASH_RESULT_OK;
}

SpiFlashOpResult IRAM_ATTR
   user_flash_erase_block(uint32 block_num)
{
    uint32 chipsize = flashchip.chip_size; // backup org chip size
     flashchip.chip_size=USER_FLASH_SIZE_BYTE;
    uint8 status=0;
    vPortEnterCritical();
   status = flash_erase_block(block_num);
   vPortExitCritical();
   flashchip.chip_size = chipsize; // restore chip size
    return status;
}





user_rw_flash_16Mbyte_rtos.h

Code: Select all

#include "esp_common.h"

SpiFlashOpResult user_flash_erase_sector(uint16 sector);
SpiFlashOpResult user_flash_write(uint32 des_addr, uint32 *src_addr, uint32 size);
SpiFlashOpResult user_flash_read(uint32 src_addr, uint32 *des_addr, uint32 size);
SpiFlashOpResult user_flash_erase_block(uint32 block_num);

piersfinlayson
Posts: 5
Joined: Tue Mar 08, 2016 1:03 am

Re: Using > 32Mb (>4MB) flash

Postby piersfinlayson » Thu Oct 13, 2016 2:20 am

Thanks Greg - will give it a go.

piersfinlayson
Posts: 5
Joined: Tue Mar 08, 2016 1:03 am

Re: Using > 32Mb (>4MB) flash

Postby piersfinlayson » Thu Oct 13, 2016 4:11 am

I got this working, but did hit a problem. The memory address that flashchip points to (0x3fffc714) actually contains a pointer to the SpiFlashChip struct, which is located at 0x3fffc718.

Therefore reading flashchip.chip_size gave 0x1640ef (presumably actually the deviceId, with the 18 for 16MB set to 16 instead). block_size was 0x400000, which was the configured flash chip size (4MB) in byte[3] of the flash. So everything was out by a word.

Once I created my own pointer to _flashchip at 0x3fffc718 and accessed chip_size from here it all started working.

Perhaps the linker line:

Code: Select all

PROVIDE ( flashchip = 0x3fffc714);


Should actually be:

Code: Select all

PROVIDE ( flashchip = 0x3fffc718);


?

You can see my test app here:

https://github.com/piersfinlayson/esp-sdk-samples/tree/master/eeprom

piersfinlayson
Posts: 5
Joined: Tue Mar 08, 2016 1:03 am

Re: Using > 32Mb (>4MB) flash

Postby piersfinlayson » Fri Oct 14, 2016 4:40 am

Actually I think the sample code is in error, and should be:

Code: Select all

extern SpiFlashChip *flashchip;

Who is online

Users browsing this forum: No registered users and 8 guests