Jump to content

Writing Eeprom In Pic18f2420


Recommended Posts

Hi Guys,

 

I've been chasing a "can't write EEPROM" problem that looks like is't a compiler/chip incompatibility.

 

Microchip's "required sequence" to do the write is:

	MOVLW 0x55
MOVWF EECON2
MOVLW AAh
MOVWF EECON2
BSF EECON, WR

But BoostC seems to be generating:

	MOVLW 0x55
MOVLB 0x0F
MOVWF gbl_eecon2
MOVLW 0xAA
MOVLB 0x0F
MOVWF gbl_eecon2
MOVLB 0x0F
BSF gbl_eecon1,1

even with the "required sequence" written as an inline asm{} block.

 

Microchip commented thus:

 

--------8<--------------------------------------------------------------

Description: Unable to write internal EEPROM.

Resolution: Thank you for attaching the disassembly. This shows where the problem is.

        MOVLW 0x55
       MOVLB 0x0F
       MOVWF gbl_eecon2
       MOVLW 0xAA
       MOVLB 0x0F
       MOVWF gbl_eecon2
       MOVLB 0x0F
       BSF gbl_eecon1,1

The 'required sequence' of writing 0x55,0xAA to the EECON2 register must be followed before the WR bit can be set. Referring to the disassembly above, the reason the WR bit cannot be set is because there is an interruption in the middle of the required sequence, i.e. 'MOVLB 0x0F'.

 

I am not sure why this compiler generates banking instructions such as this when SFRs are accessed because they reside in Access RAM. This seems inefficient.

 

If using inline assembly in the C code allows you to avoid the 'MOVLB' instructions in the above sequence then this should allow the WR bit be set and the write should succeed.

--------8<--------------------------------------------------------------

Link to post
Share on other sites
  • 15 years later...

I'm getting this exact problem when trying to enable the RTC on the PIC18F27J53. This requires an

eeprom2 = 0x55; eeprom2=0xAA; set_bit(rtccfg, RTCWREN);

sequence and whatever I do I get the spurious movlb 0x0f instruction in the middle of the sequence, which breaks the operation. I've even tried 

asm
    {
        movlw    0x55
        movwf    _eecon2
        movlw    0xAA
        movwf    _eecon2
        bsf        _rtccfg,RTCWREN
    }

Which generates

2834  0E55          MOVLW 0x55
2836  6EA7          MOVWF gbl_eecon2
2838  0EAA          MOVLW 0xAA
283A  6EA7          MOVWF gbl_eecon2
283C  010F          MOVLB 0x0F                          <-----
283E  8B3F          BSF gbl_rtccfg,5, 1
 

This bank switch instruction isn't necessary and it breaks the RTCCFG sequence which consequently fails. Is there *any* way of getting the compiler to not generate this bank switch?

I'm using Sourceboost IDE version 7.30 with C compiler 7.30 and linker 7.30 under Windows 7

Link to post
Share on other sites

Well, I think I may have fixed this. Secret is to use a MOVFF instruction to load data into the RTCCFG register

    // Unlock the RTCCFG register
    rtccfg_tmp = rtccfg;
    set_bit(rtccfg_tmp, RTCWREN);
    asm
    {
        movlw    0x55
        movwf    _eecon2
        movlw    0xAA
        movwf    _eecon2
        movff    _rtccfg_tmp, _rtccfg
    }

rtccfg_tmp is a global unsigned char and because the MOVFF instruction doesn't need a bank switching register the compiler doesn't put a MOVLB instruction into the middle of the load sequence.

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...