Saving settings in PIC memory.

Discussion in 'Programmer's Corner' started by R!f@@, Oct 7, 2016.

  1. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,729
    759
    I have a project coming up using a 16F886.
    I can do all the necessary coding but one part.

    The part consists of a variable that will be set up during a setup mode. Set up mode is done by the customer end and setting is input via an encoder. Once set up, I need to retain the value .

    I believe I can do the setting routine but saving the value to the EEPROM is something I haven't done yet.

    I believe I will be asked about the value. I cannot disclose what the program does cause it is not mine once I make it.
    The variable is a preset time delay counter. It can be set up at 30 minute increment up to 12 Hrs. So 24 Increments. Once set up the timer uses that value to time an output. I know I can use that value indefinitely as long there is no power outage. An unexpected reset like a brown out is my concern as will reset the value to initial value (30 minutes).
    I like some pointers on how to save the variable in to the memory. Continued writing to EEPROM won't be there, cause once set up it will remain like that for months.
     
  2. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,671
    897
    That chip has High Endurance Flash (HEF) and EEPROM. You can use either and the routines for using them are similar. Unfortunately, I do only assembly so sharing code probably won't help you.

    Both durable memories have limited writes. HEF is less. In the code where I use HEF, it is a calibration that is run at the user's demand, so I didn't think the write limitation would matter. That is a question only you can answer.

    John
     
    R!f@@ likes this.
  3. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,872
    369
    Are you using assembler (MPASM?) or C (which compiler?).
     
  4. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,018
    For setup parameters that are written infrequently I'd do something like this:
    Write the setup to EE using MikroC's library routines (I assume still MikroC?)
    Don't reset the PIC until the EE write time (a few mSec) has elapsed.
    On power up, read the EE into a variable and access that variable rather than EE - its just easier.
    I create a multi-byte record of setup variables that is checksum-protected and update setup value(s) as a record. Read the record into RAM on power up and check the checksum. Use safe defaults if it's bad (indicating a corrupt EEPROM or non-calibrated system).
    Use the brownout detector to avoid clobbering the EE during power down - it happened once to me.
    Park EEADDR when done reading/writing by setting it to a value that points away from your good data to avoid clobbering your data if it goes nuts.
    Good luck!
     
    R!f@@ and Papabravo like this.
  5. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,729
    759
    I am using MikroC Pro.
    Looks Simple enough...I will try it.
    I making proto on vero, once finished I will start with the code and get back.
    TTFN.
    Thanks again guys.
     
  6. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,729
    759
    Can you explain this part a bit more JohnInTX. :)
    Does that mean do not power down when it is been setup.
     
  7. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,671
    897
    The wait that JohninTx refers to is the time it takes to write HEF or EEPROM, which is quite long in MCU terms (2 ms) . You want to turn off interrupts while writing too. If turning off at the wrong time is an issue, you could toggle an LED to show when the write was done.

    John
     
    R!f@@ likes this.
  8. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,729
    759
    Aah !
    It can wait while saving. Since it is only done during the initial setup. Once set up, there is no more writing taking place. From there it just reads that data any time a brown out or power failure occurs.
     
  9. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,018
    Indeed. Hopefully the library routines take the delay into account and the method remains consistent over compiler versions. I had a problem with restarting the PIC after storing new setup structures when the compiler moved the delay / check for done operation from after the write to before the write. With the new version, the PIC reset fouled the write since it occurred while the EE was busy. Checking busy before the write is a better construct but it took a bit to figure that out.

    To clarify a bit, interrupts need to be disabled only during the writing of the 55h AAh sequence unless both foreground and background processes write the EE - not recommended for a lot of reasons.

    Finally, turning off the interrupts in this dog are not as simple as clearing GIE. You have to retest GIE and ensure that an interrupt did not occur during the bcf INTCON,GIE instruction. If it did, the RETFIE after interrupt service will set GIE=1 and your code sequence will not have disabled the interrupt. Its a known problem in early midrange and noted in the sample code in Example 10-2: DATA EEPROM WRITE in the datasheet. Again, look at the compiled assembler output to see that it includes the retest.

    Just one of many reasons why I won't use midrange if I can help it.
     
    jpanhalt likes this.
  10. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,729
    759
    What if I have the interrupt (all of em) completely disabled during set up.
     
  11. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,018
    That's fine but not required. You just need to be aware of those potential gotcha things.
    Write a little EE write code, compile and look at the assembler output. We can help you there but I'll bet that MikroC has it covered.
     
  12. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,729
    759
    OK...Thanks.:)
    I dunno what I would do without you guys. :p
     
  13. John P

    AAC Fanatic!

    Oct 14, 2008
    1,632
    224
    For what it's worth, here is my "MYEEPROM_write" routine, which I can easily give you because I have a window open for the project I'm working on. Written in MikroC for a PIC16F690.

    Incidentally, I made a stupid mistake in this program where I ignored the fact that once a write to the EEPROM begins, the EEPROM is locked until the write ends, and the nature of the lock is that you can't load a new value to EEADR in that time. I was going crazy trying to figure out why reads from the memory were failing (as I thought) randomly. A big "duh" on that one, but to be fair to myself, the manual doesn't mention it.

    Code (Text):
    1.  
    2. #define GLOBAL_INT_ENABLE  intcon.GIE = 1
    3. #define GLOBAL_INT_DISABLE  intcon.GIE = 0
    4.  
    5. void my_eeprom_write(char addrr, char dataa)
    6. {
    7.   while (eecon1.WR)                  // EEPROM is available?
    8.       ;                              // Wait till previous write completes, if necessary
    9.   eeadr = addrr;
    10.   eedata = dataa;
    11.   eecon1.WREN = 1;
    12.   while(eecon1.WREN == 0)            // Make sure it actually sets
    13.     ;
    14.   GLOBAL_INT_DISABLE;
    15.   while(intcon.GIE)                   // Make sure it actually clears
    16.     ;
    17.   eecon2 = 0x55;
    18.   eecon2 = 0xAA;
    19.   eecon1.WR = 1;                     // Start the write operation
    20.   GLOBAL_INT_ENABLE;
    21.   eecon1.WREN = 0;
    22. }
    23.  
     
    R!f@@ and JohnInTX like this.
  14. JohnInTX

    Moderator

    Jun 26, 2012
    2,338
    1,018
    Hi John. I'm pretty sure you need to put GLOBAL_INT_DISABLE within your while(intcon.GIE) loop. If for some reason you get caught in the problem I described it will hang.
    Best,
    J
     
  15. John P

    AAC Fanatic!

    Oct 14, 2008
    1,632
    224
    Thank you John, now you point that out, I'm certain that you're right. I put that test in the code with some vague idea that clearing the GIE bit might be delayed somehow, but the point is really that I could clear it and then it might be reset by an interrupt, and my test wouldn't catch that. I'd set up the worst kind of bug, the sort that only appears very occasionally.

    I think the right way to do it is (with a new #define to be consistent):
    Code (Text):
    1.  
    2. #define TEST_GIE intcon.GIE
    3.  
    4.    do {
    5.        GLOBAL_INT_DISABLE;
    6.    }  while(TEST_GIE);
    7.  
    Always clear it once, maybe clear it more than once.
     
    JohnInTX likes this.
  16. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,671
    897
    @Moderators: If this needs a new thread, please move.

    @JohnInTX (post#9)
    Thank you for that very informative comment on clearing GIE. That potential problem is clearly defined for the 16C-aged chips, see: AN576b(1997):http://www.t-es-t.hu/download/microchip/an576b.pdf

    Summary:
    However, there is conflicting information as to whether and when it disappeared with other mid-range chips. Assuming it has been resolved in the extended mid-range chips, I cannot find any discussion of how that was done or tested.

    Search details (with comments):

    1) Old (1997) Microchip recommendation (AN576b): http://www.t-es-t.hu/download/microchip/an576b.pdf
    I don't see how methods 3-6 address the problem of an interrupt occurring during the single instruction cycle that "bcf INTCON,GIE" takes.

    2) Describes problem as affecting some newer chips, but does not mention enhanced-mid-range chips:
    http://www.microchip.com/forums/m150379.aspx

    3) This discussion of enhanced mid-range chips doesn't mention the problem. Has it been fixed (how?) or is that simply an error of omission?
    http://microchip.wikidot.com/8bit:emr-interrupts

    4) PICLIST discusses several gotcha's and a comment is made that the problem with disabling global interrupts is was fixed with the 16F84 (http://www.piclist.com/techref/microchip/gotchas.htm?key=mode?? ):
    Edit: Link to 16C84 chip: http://ww1.microchip.com/downloads/en/DeviceDoc/30445D.pdf
    Problem is defined, but in Example 7-1, the solution is not used! Nevertheless RB's comment is validated in the Microchip table of differences between the two chips (Appendix E):
    upload_2016-10-8_10-54-23.png

    Question:

    I am anxious for your or anyone else's take on the current situation, particularly with enhanced mid-range chips. And as JohnP suggests, why not just clear GIE twice rather than do a loop with btfsc? Never mind.

    Regards, John
     
    Last edited: Oct 8, 2016
  17. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,729
    759
    Do I need to move to a 18F series PIC, to solve the problems ?
     
  18. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,872
    369
    Would you expect that a more complicated chip would have less gotchas. No, they are just different. Keep an eye on the errata.
     
  19. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,729
    759
    Crap !
    I an not very good at gotchas. :(
     
  20. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,671
    897
    I have not seen this matter addressed in the errata for current chips. Have you?

    John
     
Loading...