Author Topic: PIC18F67K22 can't write EEPROM  (Read 2462 times)

0 Members and 1 Guest are viewing this topic.

Offline firstcolleTopic starter

  • Regular Contributor
  • *
  • Posts: 130
  • Country: it
PIC18F67K22 can't write EEPROM
« on: April 22, 2017, 02:14:43 pm »
Hi, I'm having some troubles with writing the EEPROM memory of a 18F67K22. some detail
- 3.3v with external regulator (this mean ENVREG tied to GND)
- clock internal osc with PLL enabled (64Mhz, but the issue remain also at lower speed)
- i use my on routine but is identical with the one created with MCC, the same routine works on PIC18F26K22 and 18F46K22 and much more.
 
it seems that the byte can't be written in EEPROM. during debug the PC skip the EECON2 = 0x55 and 0xAA instruction and i can't understand why.. is there some sort of enamblig method on this PIC?
 
here is the wrtite routine..

Code: [Select]

 unsigned char GIEBitValue = INTCONbits.GIE;

    EEADR = (data_address & 0xFF);
    EEDATA = data_byte;
    EECON1bits.EEPGD = 0;
    EECON1bits.CFGS = 0;
    EECON1bits.WREN = 1;
    INTCONbits.GIE = 0; // Disable interrupts
    EECON2 = 0x55;
    EECON2 = 0xAA;
    EECON1bits.WR = 1;
    // Wait for write to complete
    while (EECON1bits.WR)
    {
    }

    EECON1bits.WREN = 0;
    INTCONbits.GIE = GIEBitValue; // Restore interrupt enable
many thanks
« Last Edit: April 22, 2017, 02:20:15 pm by firstcolle »
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: PIC18F67K22 can't write EEPROM
« Reply #1 on: April 22, 2017, 06:44:06 pm »
it seems that the byte can't be written in EEPROM. during debug the PC skip the EECON2 = 0x55 and 0xAA instruction and i can't understand why..
Here's what the datasheet says about how to enable writes:-
Code: [Select]
         MOVLW 0x55         ;
Required MOVWF EECON2       ; Write 55h
Sequence MOVLW 0xAA         ;
         MOVWF EECON2       ; Write 0AAh
         BSF   EECON1, WR   ; Set WR bit to begin write
         BTFSC EECON1, WR   ; Wait for write to complete
         GOTO $-2

The datasheet's explanation is a bit ambiguous, but I suspect the instructions have to be executed in sequence without anything else happening in between. So the debugger 'skips over' those instructions because they have to be executed in real-time.
 


 
 
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12865
Re: PIC18F67K22 can't write EEPROM
« Reply #2 on: April 22, 2017, 07:32:02 pm »
IIRC, from the hardware's point of view, the critical sequence is:

Tcycle    Operation
1         Write 0x55 to EECON2
2         - don't care -
3         Write 0xAA to EECON2
4         EECON1.WR bit is unlocked for this instruction only.

The write of 0x55 to EECON2 'starts the clock'.  If the write of 0xAA doesn't happen two instructions later, the WR bit unlock for the next instruction cycle is cancelled.  Anything more complex would require the EEPROM access controller to sniff the CPU core state which would require more interconnects, wasting die area and tightly coupling the EEPROM module to the core design. 
 

Offline jolshefsky

  • Regular Contributor
  • *
  • Posts: 227
  • Country: us
    • Jason DoesItAll
Re: PIC18F67K22 can't write EEPROM
« Reply #3 on: April 22, 2017, 07:49:46 pm »
I have been wrestling with the PIC internal EEPROM for a while. I still don't have a proper solution to my problem (occasional, specific writes of 0x02 when not expected) which I documented here.

What I do know, though, is that the "magic sequence" must be followed exactly:
Code: [Select]
         MOVLW 0x55
         MOVWF EECON2
         MOVLW 0xAA
         MOVWF EECON2

Two things can be a problem: interrupts, and compilers. You already have the bit to turn off interrupts, but you may have the issue that some compilers will redundantly set the RAM page bit resulting in a problem, so your snippet
Code: [Select]

    EECON2 = 0x55;
    EECON2 = 0xAA;

might actually result in something like:
Code: [Select]
         MOVLW 0x55
         BSF STATUS.RP0
         MOVWF EECON2
         MOVLW 0xAA
         BSF STATUS.RP0
         MOVWF EECON2

which does not work and the processor ignores it (no EEPROM write). You may need to add an assembly snippet in your routine to ensure this doesn't happen.
May your deeds return to you tenfold.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: PIC18F67K22 can't write EEPROM
« Reply #4 on: April 23, 2017, 07:47:02 am »
Quote
EEADR = (data_address & 0xFF);
Watch out for this as EEADR is defined as an unsigned char even though it would seem that should address the whole register pair (it would seem they did this to match the datasheet naming).  There is only EEADR and EEADRH. The EEADRH is supposed to be 00 on reset, so unless you are setting either of those bits somewhere else, it should not matter. If you are touching those bits somewhere else, then it would matter as the EEADRH is not set in your code you have shown. Since you are and'ing the data_address with 0xFF, I assume you are working with a 16bit data_address, and possibly assuming EEADR is also 16bits. In any case I would set EEADRH-
EEADR = data_address;
EEADRH = data_address >> 8;
 

Offline firstcolleTopic starter

  • Regular Contributor
  • *
  • Posts: 130
  • Country: it
Re: PIC18F67K22 can't write EEPROM
« Reply #5 on: April 23, 2017, 08:27:37 am »
the problem was the compiler.. infact the ASM code was generated without the
Code: [Select]
         MOVLW 0x55
         MOVWF EECON2
         MOVLW 0xAA
         MOVWF EECON2

i solved the problem using
Code: [Select]
            asm("MOVLW 0x55");
            asm("MOVWF EECON2");
            asm("MOVLW 0xAA");
            asm("MOVWF EECON2");

 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: PIC18F67K22 can't write EEPROM
« Reply #6 on: April 23, 2017, 08:37:45 am »
which compiler? XC8 doesn't skip those instructions, infact on some of the newer pic16/18 datasheets the code is given out in C directly.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12865
Re: PIC18F67K22 can't write EEPROM
« Reply #7 on: April 23, 2017, 08:45:52 am »
That doesn't guarantee the problem will stay solved if you add code to the program, change optimisation level or upgrade the compiler.  If you have
Code: [Select]
            asm("MOVLW 0x55");
            asm("MOVWF EECON2");
            asm("MOVLW 0xAA");
            asm("MOVWF EECON2");
            EECON1bits.WR = 1;
the compiler may choose to insert instructions between the last asm() statement and setting the WR bit in C.  To make sure it stays fixed, you *MUST* set the WR bit using an assembler BSF instruction.

@JPortici: There's a known issue with some versions of the compiler - at high optimisation levels, if you have more than one EEPROM unlock sequence in the program, the optimiser may recognise the code duplication and replace all copies with a subroutine call to a single copy.  Unfortunately, the optimiser sometimes isn't aggressive enough  and fails to put the following BSF EECON1,1 in the subroutine, which causes the subroutine RETURN to break the critical unlock sequence.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: PIC18F67K22 can't write EEPROM
« Reply #8 on: April 23, 2017, 04:59:38 pm »
Quote
the problem was the compiler.. infact the ASM code was generated without the
Seems odd ANY compiler would optimize away writing to volatile defined registers. You write to a volatile, the compiler will be writing to that register- maybe not in the required time frame, but it will write to it. If not, then we are all in big trouble.

The OP's code posted will compile correctly (required time frame) in XC8/v1.41/Free, it will also work for 16F.

Procedural abstraction in XC8 only works in PRO mode, but even if that is happening here (PRO mode user asking questions here?), the OP surely could see the call taking place to that code if that is what happened. We are missing some information it seems.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf