Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

EEPROM Write: Why Clear WREN Multiple times?

Status
Not open for further replies.

jpanhalt

Well-Known Member
Most Helpful Member
Here is the EEPROM write procedure for the 12F1840:
upload_2015-10-17_14-30-57.png

Why is the last step "GOTO $-2" instead of "GOTO $-1?"

Other Microchip documents I have consulted, such as DS31007A do not explain the need for clearing WREN more than once.

John
 
There must be a bit missing here!!! WREN has to be set before the write then cleared after the write..

I had trouble with Microchips EEprom routines so I made this write routine ( It's in C but so low level it matters not!!)
C:
void WriteEeprom( unsigned int badd,unsigned char bdata )
   {
   EEADR = (badd & 0x0ff);
   EEDATA = bdata;
   EECON1bits.EEPGD = 0;
   EECON1bits.CFGS = 0;
   EECON1bits.WREN = 1;
   INTCONbits.GIE = 0;
   EECON2 = 0x55;
   EECON2 = 0xAA;
   EECON1bits.WR = 1;
   while(EECON1bits.WR);
   INTCONbits.GIE = 1;
   EECON1bits.WREN = 0;
   }

Notice I wait until the end to clear the write enable...

The goto $-2 is to go back two lines to test again.. Once the test is clear the goto is jumped!!
 
Yes, to save space, I only showed the clip clearing WREN however many times it takes for WR to clear. Here is the whole Microchip procedure:
upload_2015-10-17_14-55-49.png


That doesn't change my question, though.

From my little understanding of C, you just sit on WR and wait for it to clear, which is what a "GOTO $-1" would do. I guess since your program works, I will just use the $-1 too.

Since the one of the stated purposes of WREN is to prevent accidental writes to EEPROM, I also wondered why the MC sequence enabled interrupts before ensuring that the write was completed. Since I am not using interrupts, though, that wasn't an issue. Your sequence is better and makes sense, but I would still clear WREN before enabling GIE, if only to be completely done with the EEPROM write before moving on.

I have used flash memory before, and effectively that (i.e., finish the whole process before enabling interrupts) is what I did there. Does flash memory take longer to write than EEPROM?

Thanks,

John

PS: This is being done to store a calibration value for the AD9850 DDS module.
 
Last edited:
Are you sure that code is for a 16 series chip and not an 18 series?

Edit, just found the datasheet and I think it's just been overlooked when copied from a 18 series datasheet. It's one of the reasons why I hate the use of goto $-n type code, it's just not good practice.

Mike.
 
I had many issues with eeprom writes so I moved the interrupt out of the way and only then disabled the write protect... I have never had an issue since...

The goto $-1 only loops in one line of code..... To go back to test the WR flag you need to step back twice!!!! ie.. goto$-2
other wise the code would hang as the goto $-1 is a forever loop...

DDS!!! I am trying to generate one using a pic12f1840.... I have nabbed some code of the net!!! It seems to work... I need a sound effect for a model my son is making.... It will be a plasma gun sound and effect...
 
At what stage during the (pipelined) execution of an instruction does the program counter increment? If early on, then wouldn't $-2 be needed to loop it back to the BTFSC instruction?
 
Pommie: That snippet was directly from the 12F1840 datasheet. I guess one could say it is a 16 series. Definitely not 18 series.
Ian:
I use this test in everything I write:

upload_2015-10-18_4-3-17.png


$-1 goes back one step. If it didn't then the code would never run. I use GOTO or BRA depending on the chip, but for that step, it really shouldn't matter.

Yes, DDS with the 12F chip and a cheap module. Took a whole month to get to me. Almost everything for those modules (eBay, ugh) is in C and most of that is for the Arduino. Found a very good, collaborative project done in Assembly by a bunch of radio hams here: https://www.vk5tm.com/homebrew/dds/dds.php (TM = Terry Mowles). At the bottom of that link is a list of the collaborators. As I recall, that collaboration began in the late 90's. There is even a more recent edition by Craig Johnson (AA0ZZ) from January, 2007. They have added a lot of neat enhancements over the years, and Johnson's code prints to 31 pages. My goal is to adapt that tome to something simple and dirty. For example, only two push button switches will be used, no rotary encoder, no LCD output, and simplified frequency selection. They have a nice calibration procedure that allows fast and slow changes of the calibration setting. I will probably eliminate the fast and make any big adjustment by manual calculation and reprogramming the chip, after I find out what the unadjusted error is.

John
 
alec_t
I see what you are driving at with the fetch process MC uses, but that is not how the "GOTO $" instruction/operator works. From the MPASM instructions:
upload_2015-10-18_4-39-41.png


Thus, "$" is the PC for the current instruction, and "$-1" counts back to the just previous instruction. Whether the instruction is one or two clock cycles does not affect the PC.

John
 
Almost everything for those modules (eBay, ugh) is in C and most of that is for the Arduino.
How is your knowledge of C coming along!! If you ever need anything translated!!!

Bra $-1 and goto $-1 decrements the PC by 1.... In other words they execute the same line..

If you have the code you posted
upload_2015-10-18_4-3-17-png.94770


that should really be bra $-2, to go back to the test!! It's the test that skips the bra instruction... I don not believe that code should work...
 
Ian, I don't see your point. When using a LF tuning fork oscillator (e.g., 32.768 KHz) the time for a stable signal (I used an LED when that bit flipped) is quite noticeable.
If I write

loop : goto loop

It's the same as

goto $-1


Unless I'm missing something

They are not the same. "goto $-1" goes to the PREVIOUS instruction, which needs to be a branch, such as BTFSS/BTFSC. If you did something like a "NOP" as the previous instruction, then it will loop forever or time out. I have seen examples of doing that intentionally, but it is rare. The "bit test, skip if true" instruction provides an escape from the loop.

As for waiting for the oscillator to stabilize, when using a LF tuning fork oscillator (e.g., 32.768 KHz), the time for a stable signal (I used an LED when that bit flipped) is quite noticeable. When I simulate with MPLab SIM, which doesn't use the chip's oscillator, I comment out those two lines. On occasion, I have forgotten to un-comment the lines and programmed the chip. Proceeding without a stable oscillator can give unpredictable results.

BTW, except for this particular and similar situations of testing a flag, I rarely use "goto $± x". I use a label as Pommie suggests.

John
 
Just looked for an errata on this question and found nothing. However, for the newer 12F1822 chip, MC has changed the recommended EEPROM write example to:

upload_2015-10-18_6-21-3.png


Note, it no longer checks the write complete flag (EECON1,WR), and has substituted two NOP's. The write enable bit is then cleared followed by enabling interrupts. That sequence is similar to the recommended sequence for writing to program space, e.g., this sequence from the 16F1519 (2013 version):

upload_2015-10-18_6-29-12.png


Of course, "PM" denotes a write to durable program memory space, not EEPROM, but the transliteration from one sequence to the other seems obvious. In fact, the suggested sequence for writing to flash program memory of the 12F1840 (2015 version, Exampl 11-5 at bottom) is identical, except for substituting EE registers for PM registers:

upload_2015-10-18_6-40-10.png


So, I will just try the two NOP's. Sure wish MC had a little better consistency with its current revisions.

John
 
Thus, "$" is the PC for the current instruction, and "$-1" counts back to the just previous instruction.
Thanks, John. I've done little PIC programming and never used the $ designator. It shows!
 
My Apologies.... I have just done a test.... I don't play with asm enough anymore....

goto $ is the forever loop!! Sorry, I should be made to eat humble pie....

I think someone at Microchip has copied the code over without thinking (As i did)..

The command should be goto $-1 as you have been saying.... ( BTW I tested it on a pic12f1840!!! )
 
Here's my conclusion. There are at least four options for that segment of code:
1) It is really necessary to keep clearing EECON1,WREN and the reason is not documented.
2) The $-2 was a typo and $-1 was intended.
3) Going back an extra step was needed to waste a little more time, knowing that no harm is done by clearing WREN multiple times.
4) This particular section was not updated along with corresponding sections for similar chips.

I suspect the answer(s) is #3 and #4; however, a comment certainly would help at that step. It is probable that the 12F1840 processor stalls in writing to the EEPROM just as it does when writing to flash program memory, since the same registers are involved.

REQUIRED SEQUENCE TO WRITE TO FLASH PROGRAM MEMORY (12F1840 datasheet):
upload_2015-10-18_11-6-34.png


I hadn't noticed that the EECON registers were being used with the 12F1840 when writing to program memory. My previous experience was with the 16F1519 for which the registers used to write to program memory are named differently (see: post #13, middle image). My bad.

Conclusion:
I will just add two, NOP's and omit checking EECON1,WR. If that doesn't work, then I will add that check. Writing to program memory can be simulated with MPLab SIM and the 16F1519, but there are things that simulate with the 16F chip that don't with the 12F chip (e.g., capture), so I can't trust the simulation to tell me it isn't working.

John
 
Hi,

Here is the complete code for the way i did it using a 16F688. Dont know if the 18 series is different. This is the exact code line by line of the routine "Write_EEPROM_Addr_w"...

Code:
Write_EEPROM_Addr_w  ;load w with address, load EEWriteData with data, then call here

TryDisableInts
  bcf INTCON,GIE  ;disable ints
  btfsc INTCON,GIE
  goto TryDisableInts

  bsf STATUS,5  ;bank 1 (all EEPROM regs are in bank 1)
  movwf EEADR  ;set addr
  clrf EEADRH  ;set high addr to 0 (16F688)

  movf EEWriteData,w  ;get data  (shared memory)
  movwf EEDATA  ;place data

  bcf EECON1,EEPGD ;enable EEPROM writes

  bsf EECON1,WREN  ;enable eeprom writes (rem for testing and unrem when ready)

  movlw 0x55  ;start of required sequence
  movwf EECON2
  movlw 0xAA
  movwf EECON2
  bsf EECON1,WR  ;start of write, end of sequence
WaitForEEPROMWriteComplete
  btfsc EECON1,WR
  goto WaitForEEPROMWriteComplete
  bcf EECON1,WREN ;disable any more EEPROM writes
  bcf STATUS,5  ;back to bank 0 before return
  ;bsf INTCON,GIE  ;enable ints
  return
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top