- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Solved! Go to Solution.
- Labels:
-
PSoC 4 Architecture
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
}
........
........
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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();
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
i tried the same with my project and i see that the data is saved in flash. Can you attach your project?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can do a simple assignment operation like:
ramData = rowData
You don't need special APIs to read data from flash in the code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
// 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now it works!
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!