Sending data via SPI to S25FS256S

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

cross mob
BeBa_4652076
Level 1
Level 1
First like given

Hello,

i am currently trying to send data to the S25FS256S flash using SPI.

Unfortunately i am running into some unexpected behaviour and can't find the reason for it.

I am using the PULPissimo platform to simulate and run my C-code.

The problem is as follows:

When i try to send some test data to the flash i can send the first batch without a problem.

In my case the data is stored in 84 registers with 32 bit width.

My simulation shows that every entry of the flash is 32 bit but i can only write the lower 8 bit of every entry for some reason but that might be because of the simulation software i use.

So after writing the first batch of data into flash i have 672 entries.

But if i want to send another 84 registers then i get some unexpected behaviour.

Now my first 512 entries are fine (i send 256 bytes then another 256 bytes then the remaining 160 bytes).

But the last 160 bytes are not the correct ones.

The next 672 bytes from my second batch are fine (but i suspect that if i would send a third batch of data the last 160 bytes of this one would be wrong too).

I double checked the ammount of data to be send as well as the address.

I can provide additional information like the code or software i am using, etc. but maybe someone already has an idea where i made a mistake.

Thank you,

Benjamin

0 Likes
1 Solution

Hi Benjamin,

I would like to inform you about addressing wrapping that takes place during Page Program operation. As you already might be aware that S25FS256S device offers two buffer sizes, 256 bytes and 512 bytes. The default setting is 256 bytes buffer, and as per my understanding, your device is working in the default setting. The buffer size can be changed to 512 bytes by changing the CR3V[4] bit. The buffer size also determines the page size of the device.

During program operation, if the data overflows the current page which is being programmed, then the address gets wrapped around the same page and program operations starts from the first address of the same page. The following explanation is from section 9.5.2 Page Program (PP 02h or 4PP 12h) on page 111 of the S25FS256S Datasheet -

pastedImage_0.png

In your application, when the first batch of 672 bytes of data is programmed to the flash, the last byte of data will be programmed to 0x029F memory location. And according to 256 byte buffer size setting and considering the fact that programming has started from the zeroth memory location of the flash, 0x029F memory location will fall somewhere in the middle of third page, since the 672 bytes of data is being programmed in chunks of 256 bytes, 256 bytes and 160 bytes. So, the last byte is programmed to the 160th location in third page.

Now, when the second batch of 256 bytes of data starts getting programmed, programming starts from the 161st location of third page. When the 256th location of third page is reached address gets wrapped and programming starts from the 1st location of third page.

As per my understanding, I could not find any logic implemented to tackle address wrapping at page boundaries in the code shared by you. Could you please let me know if address wrapping has been considered in your code or not? If not, could you please try to implement a logic for this and let us know if you are getting the correct output? Please let me know if you have any further queries.

Best Regards,

Apurva

View solution in original post

5 Replies
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi Benjamin,

Thank you for contacting Cypress Semiconductor.

Could you please elaborate a little on what do you mean by "last 160 bytes are not the correct ones"? Are you reading the incorrect data back after programming or the programming isn't happening at all?

Please tell us the exact steps that you are following or if possible please provide the code.

Best Regards,

Apurva

lock attach
Attachments are accessible only for community members.

Hello Apurva,

i have attached the test data small_set.txt and my code test.c in this post.

To simulate the PULPissimo platform which i mentioned in my first post, i am using Questasim.

Basically my test data is in the format "32.bit.address_64bit.data".

This means that after loading the test data into the memory of the platform, one batch consists of 168 32 bit registers that contain data that i want to load to flash and 2 registers that contain data which i don't want to load. I am using those last two so i can check if i loaded in the correct ammount of data. So for the whole test data this would mean 4x168 32 bit registers that i want to load.

The first batch that i want to load goes from 1C020000 to 1C020298.

After the bulk erase all my entries in the flash look like this in Questasim:

000000ff

If i only load the first batch from my test data (1C020000 to 1C020298) my flash memory looks like this:

address start (hex)address end (hex)data (hex)
000000000000000700000011
0000000800000297000000aa
000002980000029f000000bb
00002a0end000000ff

This works as expected. But if i want to load the second batch from my test data (1C030000 to 1C030298) after loading the first batch it looks like this:

address start (hex)address end (hex)data (hex)
000000000000000700000011
00000008000001ff000000aa
000002000000029f00000088
000002a0000002a700000022
000002a800000437000000cc
000004380000043f000000dd
000004440000049f000000ff
000004a0000004ff000000cc
00000500end000000ff

As you can see the first 512 entries (up to address 000001ff) are still correct. Then instead of aa i have 88 which looks suspiciously like (aa & cc).

Also the part near the end of the second batch confuses me too.

I have tried several different implementations to see if those work but unfortunately none did.

It's probably a very simple and obvious mistake that i made but this is my first time trying something like this so for me it's hard to find it.

If you need any additional info please let me know.

Thank you for your help,

Benjamin

Edit: Fixed some typos and updated the c-code

0 Likes

Hi Benjamin,

I would like to inform you about addressing wrapping that takes place during Page Program operation. As you already might be aware that S25FS256S device offers two buffer sizes, 256 bytes and 512 bytes. The default setting is 256 bytes buffer, and as per my understanding, your device is working in the default setting. The buffer size can be changed to 512 bytes by changing the CR3V[4] bit. The buffer size also determines the page size of the device.

During program operation, if the data overflows the current page which is being programmed, then the address gets wrapped around the same page and program operations starts from the first address of the same page. The following explanation is from section 9.5.2 Page Program (PP 02h or 4PP 12h) on page 111 of the S25FS256S Datasheet -

pastedImage_0.png

In your application, when the first batch of 672 bytes of data is programmed to the flash, the last byte of data will be programmed to 0x029F memory location. And according to 256 byte buffer size setting and considering the fact that programming has started from the zeroth memory location of the flash, 0x029F memory location will fall somewhere in the middle of third page, since the 672 bytes of data is being programmed in chunks of 256 bytes, 256 bytes and 160 bytes. So, the last byte is programmed to the 160th location in third page.

Now, when the second batch of 256 bytes of data starts getting programmed, programming starts from the 161st location of third page. When the 256th location of third page is reached address gets wrapped and programming starts from the 1st location of third page.

As per my understanding, I could not find any logic implemented to tackle address wrapping at page boundaries in the code shared by you. Could you please let me know if address wrapping has been considered in your code or not? If not, could you please try to implement a logic for this and let us know if you are getting the correct output? Please let me know if you have any further queries.

Best Regards,

Apurva

Hello Apurva,

thank you very much for your quick and detailed answer.

I just tried it out setting the page addresses by hand to test it and it worked perfectly!

Just one more question: Is there a way to disable address wrapping or does the user have to implement logic or functions to handle it?

From what i read in the Datasheet i'm not sure.

It says on page 67:

02h Volatile CR3V[4]: This bit controls the Page Programming Buffer address wrap point. Legacy SPI devices generally have used a 256-byte Page Programming Buffer and defined that if data is loaded into the buffer beyond the 255-byte location, the address a twhich additional bytes are loaded would be wrapped to address zero of the buffer. The S25FS-S family provides a 512-byte Page Programming Buffer that can increase programming performance. For legacy software compatibility, this configuration bit provides the option to continue the wrapping behavior at the 256-byte boundary or to enable full use of the available 512-byte buffer by not wrapping the load address at the 256-byte boundary.

Does this mean that if i use the 512-byte buffer the address wrapping is disabled, or does it mean that it is wrapped at the 512-byte boundary instead of the 256-byte boundary like it does in my case right now?

Thank you for your help,

Benjamin

0 Likes

Hi Benjamin,

I would like to inform you that there is no way to disable address wrapping at page boundaries. You will have to implement a logic in your firmware to tackle it.

The above snip from the datasheet means that if the CR3V[4] bit is modified from its default setting, then the buffer size is set to 512 bytes and address wrapping will take place after 512 byte boundary instead of 256 byte boundary.

Best Regards,

Apurva