An Xfiles episode: 2 identical eeprom functions but only 1 w

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I want to create my own E2PROM driver. I wrote my own code but it didn't work.
I then found working code on the gcc-forum (I call it avre_wr_byte). In an effort to just get my
function (avreepromBufWr2) working I eventually changed it to look exactly like avre_wr_byte,
but still it doesn't work.

void avreepromBufWr2(INT8U const * dest, INT8U lenval)
{
register unsigned char sreg;

sreg = SREG;
cli();
while ( EECR & (1 << EEWE ))
{
SREG = sreg;
cli();
}
EEAR = (INT16U)dest;
EEDR = lenval; //*src_p++;
EECR |= (1 << EEMWE);
EECR |= (1 << EERE);
SREG = sreg;
} //end avreepromBufWr()

void avre_wr_byte( INT8U const * ptr, INT8U val )
{
register unsigned char sreg;

sreg = SREG;
cli();
while ( EECR & (1 << EEWE )) {
SREG = sreg;
cli ();
}
EEAR = ( INT16U )ptr;
EEDR = val;
EECR |= ( 1 << EEMWE );
EECR |= ( 1 << EEWE );
SREG = sreg;
}

The test is very simple - I write a byte and read it back in the main function.
The write is successful for eeprom_write_byte() and avre_wr_byte(), but not for
avreepromBufWr2() ??

int main(void)
{
im_src = eeprom_read_byte((INT8U*)3);
if(im_src == 0xff)
{
// eeprom_write_byte((INT8U*)0, 'K');
// avre_wr_byte((INT8U*)2, 'K');
avreepromBufWr2((INT8U*)3, 'h');
LED_ERR_ON();
}
else
{
LED_STAT_ON();
}
while(1);
}

I don't know what I'm overlooking, but please help. I use winavr, avr-gcc 3.41, Jtag Ice and Astudio 4.10.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The difference as I can see: You use EERE instead of EEWE in the last EECR asigment.

birk, Norway

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I looked that code over and compared it a 100 times, I cannot believe I missed that!
Thanks, this Xfile is now closed.

regards :oops: :oops:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why you put in while loops following code:

SREG = sreg;
cli();

IMHO it will be enough to save/restore only I bit from SREG.

BTW> Why you want to write your own EEPROM handling functions? Is it some kind of an exercise?

Regards,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That part I got from the other working code (elsewhere in this forum). I think the purpose is to enable and then disable interrupts quickly so your interrupt handlers will get executed while you wait.

I write my own EEPROM driver because the libc driver has a few limitations. If you seach gcc forum you will find other posts that list them. I also call my EEPROM routines from a higher more generic external memory interface module and this module and this module requires a specific interface to its lower level functions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

johannkok wrote:
That part I got from the other working code ...... so your interrupt handlers will get executed while you wait.

This has a little sense for me because the only reason for disabling interrupts during EEPROM writing is to prevent occuring interrupts between setting EEMWE and EEWE bits.
Maybe it is another reason for using this code sequence???

johannkok wrote:
I write my own EEPROM driver because the libc driver has a few limitations .... this module requires a specific interface to its lower level functions.

It was also posted solution somewhere. You can copy original sources and compile and link them as a part of your project.

Regards,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're right. Also, interrupts only has to be disabled right before writing to EEMWE and just after writing to EEWE (that is if no ISR uses eeprom).

To be honest, my original code disabled interrupts only after the while loops, but I was so desperate to get my function working that I eventually changed it to look exactly like the other one.

Maybe someone else can tel us what is the purpose of those 2 lines in the while loop.