When to use eeprom_busy_wait()

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

I know that similar questions have been asked and replied in the past (e. g. here)but there is never a reference to the documentation or datasheet. I understand that the function "eeprom_busy_wait() " is not needed when using the read/write functions provided in <avr/eeprom.h>: eeprom_read_*(...) and eeprom_update_*(...)

 

My question is: When is it necessary then?

 

In the compiler (AVR/GCC) documentation it says:

 

  • All of the read/write functions first make sure the EEPROM is ready to be accessed. Since this may cause long delays if a write operation is still pending, time-critical applications should first poll the EEPROM e. g. using eeprom_is_ready() before attempting any actual I/O. But this functions are not wait until SELFPRGEN in SPMCSR becomes zero. Do this manually, if your softwate contains the Flash burning.

What does this mean? It says, if the application is time-critical then the EEPROM must be polled using eeprom_is_ready(). So:

  • I will verify twice (since the function itself already verifies)? would make no sense...
  • or to make sure that the write/read has been completed for example before jumping into the Bootloader Section? (I think this is what they mean)
  • or do they mean before trying to call the function again and avoid data geting lost? (this is supposed to be checked already) e. g. 
						eeprom_update_byte(&var1_e, Var2);
						eeprom_busy_wait();
						eeprom_update_byte(&Var3_e ,Var4);
						eeprom_busy_wait();

Any clarification would be appreciated

 

 

 

This topic has a solution.
Last Edited: Mon. Aug 29, 2016 - 09:41 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr_ivan wrote:
My question is: When is it necessary then?

take a look at the documentation for <avr/boot.h> - that includes an example of calling it (remember that it should be used before SPM operations as well as EEPROM ones).

avr_ivan wrote:
I will verify twice (since the function itself already verifies)? would make no sense...

It wouldn't matter would it? Once it's ready it's ready - a second call should just return immediately shouldn't it?

 

By the way none of the AVR-LibC code should really be a mystery to anyone - it's all open source. The manual:

 

http://www.nongnu.org/avr-libc/

 

tells you that the project is located at:

 

http://savannah.nongnu.org/proje...

 

and from there you can get the link to browse the SVN repository:

 

http://svn.savannah.nongnu.org/v...

 

Within that is:

 

http://svn.savannah.nongnu.org/v...

 

which contains the source code of all the functions provided by <avr/eeprom.h> for example here is eeprom_read_byte():

 

http://svn.savannah.nongnu.org/v...

 

A lot of that is the Xmega variant code. The non Xmega code is basically:

#else			/* --------------------------------------------	*/

1:	sbic	_SFR_IO_ADDR (EECR), EEWE
	rjmp	1b
# ifdef	 EEARH
#  if	  E2END > 0xFF
	out	_SFR_IO_ADDR (EEARH), addr_hi
#  else
	; This is for chips like ATmega48: the EEAR8 bit must be cleaned.
	out	_SFR_IO_ADDR (EEARH), __zero_reg__
#  endif
# endif
	out	_SFR_IO_ADDR (EEARL), addr_lo
	sbi	_SFR_IO_ADDR (EECR), EERE
	clr	ret_hi
	in	ret_lo, _SFR_IO_ADDR (EEDR)
	ret

As you can see the very first thing that is doing is:

1:	sbic	_SFR_IO_ADDR (EECR), EEWE
	rjmp	1b

which is waiting for EEWE in EECR to be clear. Back over in <avr/eeprom.h> you will have seen:

#if	defined (__DOXYGEN__)
# define eeprom_is_ready()
#elif	defined (__AVR_XMEGA__) && __AVR_XMEGA__
# define eeprom_is_ready()	bit_is_clear (NVM_STATUS, NVM_NVMBUSY_bp)
#elif	defined (DEECR)
# define eeprom_is_ready()	bit_is_clear (DEECR, BSY)
#elif	defined (EEPE)
# define eeprom_is_ready()	bit_is_clear (EECR, EEPE)
#else
# define eeprom_is_ready()	bit_is_clear (EECR, EEWE)
#endif

...

#define eeprom_busy_wait() do {} while (!eeprom_is_ready())

So the code at the top of eeprom_read_byte() is doing the same as the eeprom_busy_wait() macro.

 

If you explore the code of eeprom_write_byte() then once again you find:

#else		/* -----------[Not Xmega]------------------------------------	*/

1:	sbic	_SFR_IO_ADDR (EECR), EEWE
	rjmp	1b

# if	 defined (EEPM0) && defined (EEPM1)
	; Set programming mode: erase and write.
	out	_SFR_IO_ADDR (EECR), __zero_reg__
...

So all these functions already contain the action of eeprom_busy_wait()

 

Oh and eeprom_update_byte() is just:

#else

1:	sbic	_SFR_IO_ADDR (EECR), EEWE
	rjmp	1b

# ifdef	 EEARH
#  if	  E2END > 0xFF
	out	_SFR_IO_ADDR (EEARH), addr_hi
#  else
	; This is for chips like ATmega48: the EEAR8 bit must be cleaned.
	out	_SFR_IO_ADDR (EEARH), __zero_reg__
#  endif
# endif
	out	_SFR_IO_ADDR (EEARL), addr_lo

	sbi	_SFR_IO_ADDR (EECR), EERE

# if	 E2END > 0xFF
	sbiw	addr_lo, 1
# else
	subi	addr_lo, 1
# endif

	in	__tmp_reg__, _SFR_IO_ADDR (EEDR)
	cp	__tmp_reg__, r18
	breq	2f

# if	 defined (EEPM0) && defined (EEPM1)
	; Set programming mode: erase and write.
	out	_SFR_IO_ADDR (EECR), __zero_reg__
etc.

so is protected in the same way.

 

Therefore your sequence:

						eeprom_update_byte(&var1_e, Var2);
						eeprom_busy_wait();
						eeprom_update_byte(&Var3_e ,Var4);
						eeprom_busy_wait();

is completely pointless - those eeprom_bust_wait()s are NOT required there.

 

Feel free to explore more of the AVR-LibC source when you feel the need to understand its operation better ;-)

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

take a look at the documentation for <avr/boot.h> - that includes an example of calling it

Thanks a lot. I did

 

 (remember that it should be used before SPM operations as well as EEPROM ones).

And I think this is the best and simplest answer

 

By the way none of the AVR-LibC code should really be a mystery to anyone - it's all open source. The manual:

I knew someone would simply suggest that and I had done it. Problem is: I am unfortunately not fluent in assembly so I was just trying to understand the complires's documentation by itself

 

...I think I should start making small projects in full assembly to remember the few things I learned at the uni before they said "well, you really don't use this anymore (~2009)...let's just jump right into C"...I knew that would come and bite me in the...

 

Thanks a lot Clawson