How to store a byte into flash memory?

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

cross mob
Anonymous
Not applicable

Hello!

I am using the PSoC4 S-Series Pioneer Kit CY8CKIT-041 and i want to store a byte (or 8 Bytes) into flash memory.

Unfortunately, i could not found the emulated EEPROM component in the component catalog. I am a little confused because i read that it should support PSoC 4!?

Then i tried to use the API

uint32 CySysFlashWriteRow(uint32 rowNum, const uint8 rowData[])

But i always get returned CY_SYS_FLASH_INVALID_ADDR.

Can somebody help me and give me a short example how i can do that?

0 Likes
1 Solution
Anonymous
Not applicable

The parameter passed to the function :"rval = CySysFlashWriteRow(0x1540, rowData);" is not correct.

The first parameter should be the flash row number and not the actual address. The valid row# for PSoC 4000S is 0-255.

You can store the data only on 128 byte boundaries as each flash row is 128 bytes. The correct function call is "rval = CySysFlashWriteRow(43, rowData);"

43rd row translates to 43*128=5504 = 0x1580.

View solution in original post

19 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Principially your approach should work. Can you please post your complete project or a shortened version that shows the error so that we all can have a look at all of your settings. To do so, use

Creator->File->Create Workspace Bundle (minimal)

and attach the resulting file.

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Here is a simple example to save 8 bytes of data to flash. I am storing the data in the last flash row i.e.255th row.

I have used PSoC Creator 4.0 to create the projet.

Note that "flash write" API writes 64 bytes of data at a time for PSoC 4000S. So, even if you want to save 8 bytes of data, the API writes 64 bytes of data starting from the memory location of the 8 bytes.

0 Likes
Anonymous
Not applicable

I think, i did the same as you in your example.

1. I create an Array from type const uint8

2. I create a Variable from type uint32 for the return value

As result i got the value 1, this stands for  "CY_SYS_FLASH_INVALID_ADDR"

const uint8 rowData[8]={1,2,3,4,5,6,7,8};

uint32 rval;

int main(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    I2C_Start();

   

    rval = CySysFlashWriteRow(0x1540, rowData);

   

    if(rval == CY_SYS_FLASH_SUCCESS )

    {

        resultFlashWrite = 0;

    }

    else if (rval == CY_SYS_FLASH_INVALID_ADDR)

    {

        resultFlashWrite = 1;

    }

    else if (rval == CY_SYS_FLASH_PROTECTED)

    {

        resultFlashWrite = 2;

    }

    else

    {

        resultFlashWrite = 3;

    }

........

........

0 Likes
Anonymous
Not applicable

The parameter passed to the function :"rval = CySysFlashWriteRow(0x1540, rowData);" is not correct.

The first parameter should be the flash row number and not the actual address. The valid row# for PSoC 4000S is 0-255.

You can store the data only on 128 byte boundaries as each flash row is 128 bytes. The correct function call is "rval = CySysFlashWriteRow(43, rowData);"

43rd row translates to 43*128=5504 = 0x1580.

Anonymous
Not applicable

ok, now i did this and i assume it works.

rval = CySysFlashWriteRow(255, rowData);

But how can i check with PSoC Creator 4.1 if the data has been stored actually in the flash?

In workspace there is a window "flash security" but here i get only the information about the flash mapping and protection.

Is there a window available where i can read out the content of the flash memory?

And of course how can i readout the flash? I can't find a function CySysFlashRead();

flash.png

0 Likes
Anonymous
Not applicable

Once you save the data, you can use the PSoC programmer tool (Programs->Cypress->PSoC Programmer) and click on read button.

This will read the entire flash content and display in the window at the bottom of the tool. You can check if your data is present in the specific memory location.

ReadFlashrows.PNG

Anonymous
Not applicable

i tried to write 8 bytes startet with row 240

rval = CySysFlashWriteRow(240, rowData);

row 240 = 240 x 128 = 30720 = 0x7800

as result, i got a CY_SYS_FLASH_SUCCESS !

But when i read it out with the programmer, i can't find the values in the flash!

flash1.png

0 Likes
Anonymous
Not applicable

i tried the same with my project and i see that the data is saved in flash. Can you attach your project?

ReadFlashrows1.PNG

lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Here is my project...

0 Likes
Anonymous
Not applicable

I just downloaded your project and see that the data is saved in the flash row.

Do you have multiple kits connected to the computer?

ReadFlashrows2.PNG

Anonymous
Not applicable

You can do a simple assignment operation like:

ramData = rowData

You don't need special APIs to read data from flash in the code.

0 Likes
Anonymous
Not applicable

dche, you write

You can do a simple assignment operation like:

ramData = rowData

In my understanding, if i want readout data from flash, i have first to do a read operation from the flash row.

Can you give me an example?

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

I have attached a simple code where i save the data to flash and read back through a I2C buffer.

ptr = (uint8*)(240 *128);
for(i=0;i<8;i++)
{
i2cstruct.bytesFromFlash = *ptr;
ptr++;
}

Like i said earlier, you do not need to do special operation to read data from flash. Only writing to flash requires supervisory calls which is handled by the CySysFlasgWirteRow API.

ReadFlashrows3.PNG

Anonymous
Not applicable

thanks dche for your help! Now it works!

but one more question.

In your example you declare a pointer as uint8.

ptr = (uint8*)(240 *128);

But i mean this exceeds the value range of uint8?

0 Likes
Anonymous
Not applicable

I am not typecasting the value (240*128).

Instead i am informing the compiler that the value (240*128) is an address of a variable of type uint8. Check the * operation in the typecasting.

Anonymous
Not applicable

oh yes,

now i understood.

But how does the compiler know that this is the address of the flash memory and not the address of the RAM?

In my understanding, if i use an address of a variable i use this address in the RAM.

0 Likes
Anonymous
Not applicable

The compiler knows the address segmentation through linker script.

When you provide an address to fetch the data, the Cortex M0 controller places the address on the AHB bus and depending on the address value, either the Flash controller or the RAM controller responds with the data.

Anonymous
Not applicable

// Test for writing and reading to FLASH for PSoC 4

#include "project.h"

uint8 cnt;  // Just a counter, 8 bit wide

static const uint8 a = 0u; // Reserves a byte in FLASH and initialise it with NUL
volatile const uint8 *ptr; // Pointer to FLASH

int main(void)
{
    CyGlobalIntEnable;

    ptr = &a;       // Pointer points now to cell in FLASH, where variable "a" is saved
    cnt = *ptr;     // "cnt" holds now the content of the FLASH cell, the "ptr" points to

    cnt++;          // Increment the counter by 1

   
    Em_EEPROM_Write(&cnt, &a, 1u); // Write content of "cnt" to adress of "a" (into FLASH)

    cydelay (1000);   // Wait a second
           
    cnt--;    // Decrement the counter by 1

    Em_EEPROM_Write(&cnt, &a, 1u); // Write content of "cnt" to adress of "a" (into FLASH)

}

The word "const" informs the linker, to put the following data into FLASH.

There is no specific "Em_EEPROM_Read", because the FLASH content can be read always with "cnt=*ptr". "ptr" is volatile and therefore is read each time new from FLASH.

BR

JK

0 Likes
Anonymous
Not applicable

Now it works!

2017-12-27_14h27_05.png

I read out the flash with PSoC Programmer again and i got my data.

But how can i read out the data in software? I can't find an API!

0 Likes