regarding calculatin of sectors for erase before page write of normal and secured regions S25FL-L 128/256

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
ViV_4156156
Level 2
Level 2

Hi

   My page program nd sector erase functions are done . To erase the sectors before page write any rfefrences for calculation for the same.

if it is there It would be helpful. some thing like this ive done is this correct

void spi_flash_secure_region_program (uint16_t address, uint8_t *p_data_bytes, uint16_t size)
{
static uint16_t number_of_pages, size_of_data, last_data_block_size, counter;

int i = 0;

uint16_t startSctrAddr = address & 0x0000FFFF;
uint16_t stopSctrAddr = (address + size) & 0x0000FFFF;

int numSctrs = 1;

if (startSctrAddr != stopSctrAddr)  // Data to be written over sector boundary?
numSctrs += 1;

for (i = 0; i < numSctrs; i++)
{
  spi_flash_secure_region_erase(startSctrAddr + (i * FLASH_SECURE_REGION_SIZE_4K)); // FLASH_SECURE_REGION_SIZE_4K = 0x400
}

size_of_data = size;

if(size_of_data <= 1024)
{
  if (size_of_data % 256)
  {
   number_of_pages = (size_of_data / 256) + 1;
   last_data_block_size = size_of_data % 256;
  }
  else
  {
   number_of_pages = (size_of_data / 256);
   last_data_block_size = 256;
  }

  address &= 0x0000FFFF; // address must be aligned to 256 byte !

  for ( counter = 0; counter < number_of_pages - 1; counter++ )
  {
   spi_flash_secure_region_page_program ((address + 256*counter) ,(p_data_bytes +256*counter), 256);
  }
  // last page
  spi_flash_secure_region_page_program ((address + 256*(number_of_pages - 1)) ,(p_data_bytes +256*(number_of_pages - 1)), last_data_block_size);
}

}

void spi_flash_program (uint32_t address, uint8_t *p_data_bytes, uint32_t size)
{
static uint32_t number_of_pages, size_of_data, last_data_block_size, counter;
int i = 0;

uint32_t startSctrAddr = address & 0xff000;
uint32_t stopSctrAddr = (address + size) & 0xff000;

int numSctrs = 1;

if (startSctrAddr != stopSctrAddr)  // Data to be written over sector boundary?
numSctrs += 1;

for (i = 0; i < numSctrs; i++)
{
    spi_flash_sector_erase(startSctrAddr + (i * FLASH_SCTR_SIZE_4K)); // FLASH_SCTR_SIZE_4K - 0x1000
}

size_of_data = size;

if (size_of_data % 256)
{
  number_of_pages = (size_of_data / 256) + 1;
  last_data_block_size = size_of_data % 256;
}
else
{
  number_of_pages = (size_of_data / 256);
  last_data_block_size = 256;
}


address &= 0x00FFFF00; // address must be aligned to 256 byte !

for ( counter = 0; counter < number_of_pages - 1; counter++ )
{
  spi_flash_page_program ((address + 256*counter) ,(p_data_bytes +256*counter), 256);
}
// last page
spi_flash_page_program ((address + 256*(number_of_pages - 1)) ,(p_data_bytes +256*(number_of_pages - 1)), last_data_block_size);

}

void spi_flash_sector_erase(uint32_t address)
{
uint8_t status, dummy_var;
uint8_t addr0, addr1, addr2,addr3;
(void)(dummy_var);
addr0 = (uint8_t) (address & 0x000000FF);
addr1 = (uint8_t) ((address & 0x0000FF00) >> 8);
addr2 = (uint8_t) ((address & 0x00FF0000) >> 16);
addr3 = (uint8_t) ((address & 0xFF000000) >> 24);

ALLOW_TRANSFER; // if previous command has set EOQ

PUSH_ENQ(WREN);   // write enable command (must be done before every write !!!)
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

ALLOW_TRANSFER; // from this point all following write to PUSHR will be sent

PUSH(SE); // Sector erase command
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var); // discard one RxFIFO item

PUSH(addr3); // most-significant byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

PUSH(addr2); // most-significant byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

PUSH(addr1); // middle byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

PUSH_ENQ(addr0); // least-significant byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

do
{
  status = spi_flash_read_status_register();
}
while (status & WIP); // wait here until bulk erase is done
}

void spi_flash_secure_region_erase(uint16_t address)
{
uint8_t status, dummy_var;
uint8_t addr0, addr1, addr2,addr3;
(void)(dummy_var);
addr0 = (uint8_t) (address & 0x000000FF);
addr1 = (uint8_t) ((address & 0x0000FF00) >> 8);
addr2 = 0;

ALLOW_TRANSFER; // if previous command has set EOQ

PUSH_ENQ(WREN);   // write enable command (must be done before every write !!!)
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

ALLOW_TRANSFER; // from this point all following write to PUSHR will be sent

PUSH(SECRE); // Secured region erase command
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var); // discard one RxFIFO item

PUSH(addr2); // most-significant byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

PUSH(addr1); // middle byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

PUSH_ENQ(addr0); // least-significant byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var);

do
{
  status = spi_flash_read_status_register();
}
while (status & WIP); // wait here until sector erase is done
}

0 Likes
9 Replies
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi Vignesh,

Thank you for contacting Cypress.

I need a little more clarification regarding your question. As far as I can understand you have a specific number of bytes of data and the 'size' variable is denoting the number of bytes of data. You want to check how many sectors will this data span to, so that before you perform the page program operation, you can erase those many sectors accordingly. Please correct me if I am wrong.

For calculating the number of sectors required to be erased, one method could be to divide the data size with the size of one sector (4KB). If the obtained value is a float then round it off till the next integer value. In the function provided by you the maximum value that numSctrs can go till is 2, but there might be cases when size of data will be huge and it might span up till more than two sectors.

In case of secure region erase, since the Security Region is just 1024 bytes, that is the maximum area that you can erase.

Hope this helps.

Regards,

Apurva

0 Likes
ViV_4156156
Level 2
Level 2

I need a little more clarification regarding your question. As far as I can understand you have a specific number of bytes of data and the 'size' variable is denoting the number of bytes of data. You want to check how many sectors will this data span to, so that before you perform the page program operation, you can erase those many sectors accordingly. Please correct me if I am wrong.

----  Yes Absolutely that is what I require

For calculating the number of sectors required to be erased, one method could be to divide the data size with the size of one sector (4KB). If the obtained value is a float then round it off till the next integer value. In the function provided by you the maximum value that numSctrs can go till is 2, but there might be cases when size of data will be huge and it might span up till more than two sectors.

--- yes I found that I had made a mistake

In case of secure region erase, since the Security Region is just 1024 bytes, that is the maximum area that you can erase.

if that is the case maximum of four sectors can be erased . correct me if I'm wrong . So divide that by 1024 incase of secure region and divide by 4096 in case of normal region

for example if I have to write a page from address 20000 for a size of 40 bytes then I have to divide 40 / 4096

and it ll result in a value of 0. am I right is this correct.

and what should be done in case of a boundary considering one page is 256 bytes but its written over a boundary.

can u pl guide me on these 2 scenarios. sector erase and page program seem to work separately.

if I properly could conceive this I think I can integrate both.

Thanks In Advance,

Vignesh.V

0 Likes
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi Vignesh,

if that is the case maximum of four sectors can be erased . correct me if I'm wrong . So divide that by 1024 incase of secure region and divide by 4096 in case of normal region

>>The Security Region comprises of 1024 bytes which are divided into four groups of 256 bytes each. The address mapping for the Security Region is provided on page 24 Section 6.5 Security region Address Space of the datasheet (https://www.cypress.com/file/316171/download ). The Security Region Erase SECRE (44h) command is capable of erasing each 256 byte block of security region separately. In order to figure out how many blocks of security region needs to be erased, the data size should be divided by 256. If the value obtained is a float it should be rounded up till the next integer.

>>In case of normal region since Sector Erase (20h) command erases one 4KB sector at once, the data size should be divided by 4096. If the value obtained is a float it should be rounded up till the next integer.

for example if I have to write a page from address 20000 for a size of 40 bytes then I have to divide 40 / 4096 and it ll result in a value of 0. am I right is this correct.

>>40/4096 will give you 0.009765 and it should be rounded off to the next integer that is 1. So you should be erasing one sector which starts from address (say) 20000.

and what should be done in case of a boundary considering one page is 256 bytes but its written over a boundary.

>>In case of programming over a boundary if both pages fall in the same sector, one sector should be erased, else if both pages are in different sector, both sectors should be erased.

>>All the above calculations are based on the assumption that programming will starts at the starting address of any sector.

Regards,

Apurva

0 Likes
ViV_4156156
Level 2
Level 2

Hi,

   Thanks . I have worked on and I tested as per ur suggestion. also I tested the functions separately I mean erase the sector separately and then re program the sector with different set of values.

For secure region erase the erase seems to happen cuz I able to read the buffer values as 255 after erase.

and the value seems to be programmed after the erase.

1. For normal main flash array erase its not  happening as expected as all the read values after the erase doesn't seem to be 255

and the status value read RDSR seems to be 2

do

{

  status = spi_flash_read_status_register();

}

while (status & WIP); // wait here until bulk erase is done

status returns as 2 for other which are working it returns as 0. If I do a chip erase then its getting erased.

2. For secure region where erase seems to work correctly I'm seeing a issue

wrtflashBufsecr1[10] = {15,20,25,30,35,40,45,50,55,60};

uint8_t readflashbufsecr1[10];

uint8_t readbuf1[10];

spi_flash_secure_region_program(0x100,wrtflashBufsecr1,sizeof(wrtflashBufsecr1));

spi_flash_secure_region_read_data(0x100,readflashbufsecr1,sizeof(readflashbufsecr1));

int loopCountRead;
for(loopCountRead = 0; loopCountRead < sizeof(readflashbufsecr1); loopCountRead++)
{
char resultantflashreg3[50] = {0};
sprintf(resultantflashreg3,"flash address read value = %d\r\n",readflashbufsecr1[loopCountRead]);
}

if I read the first 10 values I get the first value as 255 the other values get written  omitting the last value

for eg 255 ,15,20,25,30,35,40,45,50,55

if I read the first 11 values I get the first value as 255 the other values get written

for eg 255 ,15,20,25,30,35,40,45,50,55,60

why this could happen a shift of one array .? Any suggestions on these two issues would be appreciated.

Regards,

Vignesh.V

0 Likes
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi Vignesh,

For a better understanding of the problem could you please provide us the waveforms for both the erase operations and your full code.

Regards,

Apurva

0 Likes
ViV_4156156
Level 2
Level 2

Hi,

    Due to some reasons I m not able to give the entire project but I'm sharing the SPI interface file which is the point of discussion.

Unfortunately there are no test points for to get it effectively probed and as its to be taken out from the chip's pin directly at the moment unable to give you the waveform.

Kindly let me know how to share because I'm not able to find any attach file here. I need to attach 2 text files

Regards,

Vignesh.V

0 Likes
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi Vignesh,

While typing your reply, you will see a "Use advanced editor" option at the top right corner of the message box. Click on it, and it will reload the message box. Upon reloading, you will find an "Attach" option at the bottom right corner of the box. You can attach files from there.

Regards,

Apurva

0 Likes
ViV_4156156
Level 2
Level 2

Hi,

    I have attached the files.

Regards,

Vignesh.V

0 Likes
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi Vignesh,

Upon going through your code, I noticed that -

  • You are using 4 bytes of address inside spi_flash_sector_erase(uint32_t address) function. In order to be able to use 4 bytes of address with SE (20h) command you need to set the CR2V[0] bit to 1, else the device will ignore the SE command and erase operation will not happen.
  • While calculating the number of sectors to be erased, you should also consider the case when num_of_sector = size / 4096 will come out to be a floating number which is greater than one (say 2.5). For that case also num_of_sector variable will have to be incremented by one, else num_of_sector will take the value as 2 and erase only 2 sectors.
  • The values that you are reading from the secure region are actually correct. If you go to page 37 of the datasheet (https://www.cypress.com/file/316171/download ), you will find the table for latency code cycles. For security region read, 8 dummy cycles are required. Hence, for the first byte of data that if being read (255), the flash is not driving the SO. The flash starts driving the SO line after the completion of 8 dummy cycles. Hence the output obtained is an expected behavior of flash.

Regards,

Apurva

0 Likes