Jump to content
Sign in to follow this  
gordon@cil-uk.co.uk

Writing Internal Eeprom In Pic18f2420

Recommended Posts

Hi guys,

 

I'm trying to write to the internal EEPROM of a PIC18F2420, but I don't seem to be able to get it to write. Everyhting I try leaves the data unchanged and has the WRERR flag set in eecon2.

 

Here follows what I'm using, showing a couple of variations I've tried (thjough I've tried _many_ more).

 

The code never (well, > 10 seconds) exits from the final while loop.

 

Anyone see a deliberate error in here please?

 

void
eeprom_write(char address, char data)
{
   // Pause here if still writing previous data
   //
   while(eecon1 & (1<<WR) );
   // while(pir2 & (1<<EEIF) );

   // Write the next data
   //
   eeadr = address;
   eedata = data;
   
   clear_bit( eecon1, EEPGD );
   clear_bit( eecon1, CFGS );
   clear_bit( eecon1, WRERR );
   set_bit( eecon1, WREN );

   clear_bit( intcon, GIE );	// disable interrupts

#if 0
   eecon2 = 0x55;
   eecon2 = 0xAA;
#else
   asm
   {
MOVLW 0x55
MOVWF _eecon2
MOVLW AAh
MOVWF _eecon2
   }
#endif
   set_bit( eecon1, WR );
   clear_bit( eecon1, WREN );

   set_bit( intcon, GIE );	// enable interrupts

   while(eecon1 & (1<<WRERR) );
}

TIA

Gordon.

Share this post


Link to post
Share on other sites

I have not written to eeprom on PIC18 before only PIC16 but I would have said that you were doing it correctly.

However after reading the PIC 18 data sheet I'm not sure, there's one of those badly phrased doubts where a simple sentence to clarify would have helped.

eg

 

In PIC16 it says...

 

After a write sequence has been initiated, clearing the

WREN bit will not affect this write cycle.

 

On this subject PIC 18 says...

 

nothing

 

However looking at the code sample they give it refers to "user code execution" followed by clearing wren. There's also some talk about monitoring the interrupt flag.

 

My guess is they have 'improved' the eeprom and that you cant clear the wren till the write has completed.

Share this post


Link to post
Share on other sites
I have not written to eeprom on PIC18 before only PIC16 but I would have said that you were doing it correctly.

However after reading the PIC 18 data sheet I'm not sure, there's one of those badly phrased doubts where a simple sentence to clarify would have helped.

eg

 

In PIC16 it says...

 

After a write sequence has been initiated, clearing the

WREN bit will not affect this write cycle.

 

On this subject PIC 18 says...

 

nothing

 

However looking at the code sample they give it refers to "user code execution" followed by clearing wren. There's also some talk about monitoring the interrupt flag.

 

My guess is they have 'improved' the eeprom and that you cant clear the wren till the write has completed.

 

I was pretty sure I'd tried that, but tried it again to be sure.

My closing lines are now:

    set_bit( eecon1, WR );

   set_bit( intcon, GIE );	// enable interrupts

   while(eecon1 & (1<<WR) );
   clear_bit( eecon1, WREN );
   while(eecon1 & (1<<WRERR) );
}

 

... but the behaviour is the same.

 

One thing I notice and that may _well_ be a clue, is that I don't actually see the WR flag set. I [allegedly] set it, but don't see it, which is somewhat suspicious.

The datasheet says it's disabled during Tpwrt, but I understand that timer has to expire before the CPU will run, so should not be implicated.

 

There are some EEPROM protect bits in the configuration data, but I have checked that they're all 'Disabled'. so again, I don't believe they can be implicated.

 

Gordon.

Share this post


Link to post
Share on other sites

Hi Guys,

 

This appears to be a conflict between BoostC's output and the PIC's "required sequence".

 

Bug report posted.

 

For completeness in this thread:

 

PIC18F2420 (and I presume others in the series) demands:

 

	MOVLW 0x55
MOVWF _eecon2
MOVLW AAh
MOVWF _eecon2
BSF _eecon1, WR

 

but BoostC, even using the above code in an inline asm{} is generating:

 

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

 

which apparently is not good enough as "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'."

 

Ho Hum.

Share this post


Link to post
Share on other sites
Hi Guys,

 

This appears to be a conflict between BoostC's output and the PIC's "required sequence".

 

Bug report posted.

 

For completeness in this thread:

 

PIC18F2420 (and I presume others in the series) demands:

 

    MOVLW 0x55
    MOVWF _eecon2
    MOVLW AAh
    MOVWF _eecon2
    BSF _eecon1, WR

 

but BoostC, even using the above code in an inline asm{} is generating:

 

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

 

which apparently is not good enough as "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'."

 

Ho Hum.

 

Most bizarre!!

 

I have got just got my existing eeprom code working .

I am using PIC18F4680 boostc18 version 6.31

This is my C + asm

	eeadrh  = 0; 
eeadr = address;
      	 eedata = writeData;
   
      	 clear_bit(eecon1,EEPGD);	// data space not program
      	 clear_bit(eecon1,CFGS);	// eeprom
      	 // enable writing
      	 set_bit(eecon1,WREN);

intconCopy = intcon;
       // special protected write sequence     
      	 clear_bit(intcon,GIE);
asm
{
	MOVLW 0x55
	MOVWF _eecon2
	MOVLW AAh
	MOVWF _eecon2
	BSF _eecon1, WR
      	 }
intcon = intconCopy;
        
       // disable writing
      clear_bit(eecon1,WREN);
   

 

NB clearing of WREN immediately

 

and generated asm (for the protected sequence)copied from list file

02AC  9EF2     	 BCF gbl_intcon,7
02AE  0E55     	 MOVLW 0x55
02B0  6EA7     	 MOVWF gbl_eecon2
02B2  0EAA     	 MOVLW 0xAA
02B4  6EA7     	 MOVWF gbl_eecon2
02B6  82A6     	 BSF gbl_eecon1,1

Share this post


Link to post
Share on other sites

Curious!

 

For compaerison and to hope it helps give a clue what's going on, here are the equivalent lines from my file.

 

I've included the entire code block and marked the relevant bit.

 

	ORG 0x00000972
0972            eeprom_wri_00008
; { eeprom_write; function begin
0972            label268437115
0972  0E02     	 MOVLW 0x02
0974  010F     	 MOVLB 0x0F
0976  14A6     	 ANDWF gbl_eecon1, W
0978  E001     	 BZ	label268437116
097A  D7FB     	 BRA	label268437115
097C            label268437116
097C  0102     	 MOVLB 0x02
097E  5106     	 MOVF eeprom_wri_00008_arg_address, W, 1
0980  010F     	 MOVLB 0x0F
0982  6EA9     	 MOVWF gbl_eeadr
0984  0102     	 MOVLB 0x02
0986  5107     	 MOVF eeprom_wri_00008_arg_data, W, 1
0988  010F     	 MOVLB 0x0F
098A  6EA8     	 MOVWF gbl_eedata
098C  0E7F     	 MOVLW 0x7F
098E  010F     	 MOVLB 0x0F
0990  16A6     	 ANDWF gbl_eecon1, F
0992  0EBF     	 MOVLW 0xBF
0994  010F     	 MOVLB 0x0F
0996  16A6     	 ANDWF gbl_eecon1, F
0998  0EF7     	 MOVLW 0xF7
099A  010F     	 MOVLB 0x0F
099C  16A6     	 ANDWF gbl_eecon1, F
099E  010F     	 MOVLB 0x0F
09A0  84A6     	 BSF gbl_eecon1,2
09A2  0E7F     	 MOVLW 0x7F
09A4  010F     	 MOVLB 0x0F
09A6  16F2     	 ANDWF gbl_intcon, F
--------8<------------------------------------
09A8  0E55     	 MOVLW 0x55
09AA  010F     	 MOVLB 0x0F
09AC  6EA7     	 MOVWF gbl_eecon2
09AE  0EAA     	 MOVLW 0xAA
09B0  010F     	 MOVLB 0x0F
09B2  6EA7     	 MOVWF gbl_eecon2
09B4  010F     	 MOVLB 0x0F
09B6  82A6     	 BSF gbl_eecon1,1
--------8<------------------------------------
09B8  010F     	 MOVLB 0x0F
09BA  8EF2     	 BSF gbl_intcon,7
09BC            label268437127
09BC  0E02     	 MOVLW 0x02
09BE  010F     	 MOVLB 0x0F
09C0  14A6     	 ANDWF gbl_eecon1, W
09C2  E001     	 BZ	label268437128
09C4  D7FB     	 BRA	label268437127
09C6            label268437128
09C6  0EFB     	 MOVLW 0xFB
09C8  010F     	 MOVLB 0x0F
09CA  16A6     	 ANDWF gbl_eecon1, F
09CC            label268437131
09CC  0E08     	 MOVLW 0x08
09CE  010F     	 MOVLB 0x0F
09D0  14A6     	 ANDWF gbl_eecon1, W
09D2  E001     	 BZ	label268437132
09D4  D7FB     	 BRA	label268437131
09D6            label268437132
09D6  0012     	 RETURN
; } eeprom_write function end

Share this post


Link to post
Share on other sites

I've just recompiled with PIC18F2420 as target and still get the correct protected sequence, I cant check it actually runs though as I had to map portd elsewhere in order to get it to compile.

Share this post


Link to post
Share on other sites

Just tried a couple of other things:

 

1) Moved the eeprom code from it's separate source file into the main source file.

The eeprom code is now virtually the first code in the main file (after a one-statement error trap).

No change.

 

2) Then switched back from MPLab to the SourceBoost IDE in case it's IDE related.

No change.

 

I'm using a slightly older compiler version (6.30), though I see no reference to changes in this area. Maybe I should update anyway :blink:

Share this post


Link to post
Share on other sites
Just tried a couple of other things:

 

1) Moved the eeprom code from it's separate source file into the main source file.

    The eeprom code is now virtually the first code in the main file (after a one-statement error trap).

    No change.

 

2) Then switched back from MPLab to the SourceBoost IDE in case it's IDE related.

    No change.

 

I'm using a slightly older compiler version (6.30), though I see no reference to changes in this area. Maybe I should update anyway  :blink:

 

I think I was mistaken about 2). I compiled but didn't link and looked at the .asm file, but I now think the .asm file wasn't rewritten.

 

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

 

Running the 6.31 compiler from SourceBoost with either a combined or a separate eeprom.c file containing the eeprom code, I get good code.

 

Running the same from MPLab, I continue to get bad code.

 

(Irritatingly, I can't cut and paste the compile report.)

Retyped significant bits from SourceBoost are (E&OE):

 

"C:\Program Files\SourceBoost\boost.pic18.exe" -t PIC18F2420 Pod.c eeprom.c

......Version 6.31 (for PIC18 achitecture)

... and the equivalent from MPLab are:

 

Executing: "C:\Program Files\SourceBoost\boostc.pic18.exe" eeprom.c -O0  -W1  -t 18F2420
BoostC Optimizing C Compiler Version 6.31 (for PIC18 architecture)
http://www.picant.com/c2c/c.html
Copyright(C) 2004-2006 Pavel Baranov
Copyright(C) 2004-2006 David Hobday

 

..which looks suspiciously like, maybe, an optimisation problem?

 

Trying that out (sounds off)

 

:lol: Turned optimisation ON and the code is right.

 

That's an inverse of the usual way on things.......

 

Just for the record, it writes the real physical EEPROM OK, too, so my problem seems fixed.

 

I still reckon that's a bug, though.

Share this post


Link to post
Share on other sites

gordon@cil-uk.co.uk,

 

..which looks suspiciously like, maybe, an optimisation problem?

 

Trying that out (sounds off)

 

Turned optimisation ON and the code is right.

 

That's an inverse of the usual way on things.......

 

Just for the record, it writes the real physical EEPROM OK, too, so my problem seems fixed.

 

I still reckon that's a bug, though.

When optimisation is turned off bank switching is applied to each and every data reference, this breaks the required sequence for the EEPROM write. When optimisation is turned on, bank switch code is only added when there is a change or uncertainty of the bank at any point in the code.

The required bank switching is added to all code, even inline assembler.

 

I don't quite think this can be regarded as a bug, its more like a feature of operation.

 

Regards

Dave

Share this post


Link to post
Share on other sites
gordon@cil-uk.co.uk,

 

..which looks suspiciously like, maybe, an optimisation problem?

 

Trying that out (sounds off)

 

Turned optimisation ON and the code is right.

 

That's an inverse of the usual way on things.......

 

Just for the record, it writes the real physical EEPROM OK, too, so my problem seems fixed.

 

I still reckon that's a bug, though.

When optimisation is turned off bank switching is applied to each and every data reference, this breaks the required sequence for the EEPROM write. When optimisation is turned on, bank switch code is only added when there is a change or uncertainty of the bank at any point in the code.

The required bank switching is added to all code, even inline assembler.

 

I don't quite think this can be regarded as a bug, its more like a feature of operation.

 

Regards

Dave

 

A note in the help file regarding what to expect from optimisation would be good.

Share this post


Link to post
Share on other sites

Pixie,

Dontcha just love them Arizona boys?
Its not their fault (this time).

 

Using BoostC in MPLABs optimisation can be turned on and off.

Goto menu Project->Build Options->Project, the select the BoostLinker tab, and there you will find optimisation on and off.

 

Regards

Dave

Share this post


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...
Sign in to follow this  

×
×
  • Create New...