Solution for Storage of Position Data With Quad Decoder

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

cross mob
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

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

0 Likes
21 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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,

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

0 Likes
lock attach
Attachments are accessible only for community members.
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

 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

0 Likes
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

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

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

 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

0 Likes
lock attach
Attachments are accessible only for community members.
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

Hi,

   

Thanks for the information.  I am trying to get the EEPROM component to work, period.  Please see the attached project.  All I want is for a two byte array to be saved between power ups.  What am I doing wrong?

   

Thank you,

   

Tom

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Small changes, large effect.

   

 

   

Bob

0 Likes
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

 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:

   

http://www.element14.com/community/thread/24155/l/psoc-4-pioneer-kit-community-project014-what-was-t...

   

This also utilizes flash storage.

   

Thank you,
Tom

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I admit, not quite correct yet: Prepend the definition of eepromArray with "volatile" to switch off the optimization.

   

 

   

Bob

0 Likes
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

 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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

A good description of "volatile" qualifier and its use -

   

 

   

    

   

          http://www.barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword    Volatile

   

 

   

Regards, Dana.

0 Likes
ToVa_285016
Level 5
Level 5
100 replies posted 50 replies posted 50 questions asked

 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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You are always welcome, Tom!

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

You are always welcome, Tom!

   

 

   

Dana.

0 Likes