- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am working on a quadrature decoder project for a friend. It is working well, but he wants to have storage of the precise position of the encoder so that if the power goes out or the machine is turned off, it remembers where it was. I have heard about the flash wearing out, and this would have to be something that could be stored many times a second when the machine is running.
Do I have to worry about it wearing out? How long will that take? Is there another non-volatile solution that I can use?
Thank you,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Endurance of flash memory is 100K write-cycles, so probably not something for multiple writes per second. Another issue might be that you need some power and some time to write flash and when power is removed during flash-write something will definitively go amiss.
A solution could be to use a gold-cap for providing power for a bit of time (10ms) and an early detection of power-loss.
Another solution could be to use an I2C interfaced FRam which is able to transfer data at up to 1MB/s. this could be enough to write off some data after a low-level voltage detect. FRam FM24V10 from Cypress www.cypress.com/
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Another solution is wear level the FLASH. That is keep track of the number of erase/write cycles,
say of a structure of data, and when you hit datasheet limit stop using that area of FLASH and
use the next area of FLASH. Use of a pointer easiest.
So say you have the 100K limit, you need 1M erase/write cycles, and you are saving 64 bytes total,
then you set aside 640 bytes, 10 sections of 64 bytes, and at 100K in section 0 start saving in section
1 by incing the pointer by 64 (if a byte pointer), at 100K in section 1 then you start using section 2........
If its a structure pointer then you inc by 1.
Regards, Dana,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Another way of doing this is use ECC each time you write the data.
Then check after write, if it is corrupted you go to the next section. This
has the potential to exceed the data sheet limits by a lot as datasheet
is worst case + some fudge factor, and your environment might not be
worst case.
There are compromises, ECC algorithim vs # bits that can be detected/
corrected.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thank you for the help. I am trying to get started with the EM_EEPROM component. I tried and failed to integrate the EEPROM into my program - see attached. This is a slightly different program than the quad decoder by the way.
All I want to do is store 3 variables in flash, and read them on power up. Please let me know what I am doing wrong.
Look specifically at the first two variables, the UpdateFlash method and the first lines of main().
Thank you,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
While trying to figure out how to store flash, I looked at this simple project:
http://pioneerkit.blogspot.com/2013/06/project014-what-was-that-value-oh-yea.html
I remember playing around with it before, and basing the first flash storage on it.
There is a problem, it no longer works on my pioneer kit. The value of the LED is not remembered. I opened Creator 3.0 and used CY_BOOT 4.11, and it worked perfectly. When I try to switch CY_BOOT back to 4.11 in Creator 3.1, it still does not work.
Unless someone has a simple explanation for this (I tend to overlook a lot), I will open a case with Cypress.
Thank you,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Some time ago I made a component for saving data to EEPROM between power-offs:
http://www.cypress.com/?app=forum&id=2492&rID=105370
Nothing special, but should work for your case. It saves to EEPROM, which should withstand about 1E+6 writing cycles, has CRC check and wearing-out capability.
You will need to add code to catch power-off event.
odissey1
- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately I am having the same effect. The variable is not saved.
As far as changes to the declarations of the array variables, I took those straight out of the example 'Em_EEPROM_Example'. Are they incorrect there?
Here is another twist. I ran this example in Creator 3.0 and Creator 3.1. It worked in Creator 3.0, but not in 3.1:
This also utilizes flash storage.
Thank you,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fortunately I am having a different effect: To prove I put an Em_EEProm_Write() after the assignment to array[] and a bp at that place. When I manually change the values for array[] and let it program by stepping over I can see that the values for eepromArray[] have been changed. Resetting the program and starting over shows that array[] now has got the manipulated value again.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I admit, not quite correct yet: Prepend the definition of eepromArray with "volatile" to switch off the optimization.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
Like you, I can put a breakpoint in and see that the value is indeed getting written to EEPROM. It just fails to read that value after reset. It once agian reads 0.
Excuse my ignorance, and let me understand what you are doing to test the situation. Where are you putting that EM_EEPROM_Write in the code and modifying 'array'? Does the system erase the flash memory on programming?
I added the code below in after 'array[1] = eepromArray[1];' and programmed the system, then debugged w/ BP right before these lines the next time, and the eepromArray indeed was set back to 0.
/* Write the SRAM array into flash */
array[0] = 127;
array[1] = 255;
status = Em_EEPROM_Write(array,eepromArray,2u);
As I asked in the last question - do you think that the delcarations in the example 'EM_EEPROM_Example' are incorrect, since you insisted on a change for this example? I should raise this with Cypress if it is the case.
Thank you for your input,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, flash is cleared before programming.
There have been a lot of changes between Creator 3.0 and 3.1, what we are fighting here right now is the underlying GCC packet and here the compiler. There have been made a lot of changes made for the actual version with focus on optimization.
So, did you already try the "volatile" trick?
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The compiler is telling me:
passing argument 2 of 'Em_EEPROM_Write' discards 'volatile' qualifier from pointer target type [enabled by default]
Does this matter? It does not change the saving of the variable.
One other thing - if the flash is cleared before programming, how can you reset the device and see the variable? Are you using UART or an LED to indicate the state? Wouldn't you just be manually setting 'array' every time so that it did not matter what the flash was?
Thank you,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is under "Debug" "Attach to Running Target" which I use after re-connecting the board to the miniprog3.
When hoovering with the mouse over a variable a window is shown telling the actual value, this is what I can check or even modify.
Without the "volatile" the compiler "remembers" that eepromArray[] was zero (0) and directly loads that value into array[] in the assignments array[0] = eepromArray[0]. This is not the case when using "volatile"
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wow, I have never used that before! Very helpful, thank you.
When I try to run with the eepromArray as volatile, it gets stuck here:
// Check for success
if (CYRET_SUCCESS != status)
It does not seem to have a successful write. Probably related to the warning the compiler gave me.
So, I see what you were saying before about testing the FLASH write. When I reset and reattach (without volatile), the flash does indeed seem to hold it's value, it is just that 'array' never gets set! It is like the following lines of code never happen:
/* Read the first two bytes out of the flash array */
array[0] = eepromArray[0];
array[1] = eepromArray[1];
Any ideas?
Thank you,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, found a solution.
the original declaration is quite correct, so use
static const uint8 CYCODE eepromArray[] = {0x01,0x03};
What goes amiss due to optimization which is quite better than it was in 3.0 is the assignment
array[0] = eepromArray[0];
array[1] = eepromArray[1];
Here the compiler "knows" that eepromArray[0] is a constant and instead of fetching its value, the compiler takes the literal constant it remembered deep inside its tables. I could not find a means to circumvent GCC to address the array, even a type-cast to (volatile uint8) did not work, which I think is a compiler bug.
Workaround:
Use memcpy() to tranfer the values from eepromArray to array as
memcpy(array,eepromArray,2);
Hope trhat helps
Bob
PS: I filed a MyCase concerning that matter.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A good description of "volatile" qualifier and its use -
http://www.barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword Volatile
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Halelujah! Thank you Bob, it does indeed work. I appreciate your help with this issue very much. This affects a couple of projects I am working on.
Thanks Dana for the link, how the code compiles and what that means to my program is something I know very little about.
Regards,
Tom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are always welcome, Tom!
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are always welcome, Tom!
Dana.