user80641: The datasheet for the ATmega328P contains this table, which describes bits 4 and 5 of EECR:




EEPM1
EEPM0
Programming Time
Operation




0
0
3.4ms
Erase and write in one operation (atomic operation)


0
1
1.8ms
Erase only


1
0
1.8ms
Write only




I'm currently working on some non-blocking EEPROM-handling code and I'm wondering when and how I should erase the EEPROM.

What does erasing do? Does it set one byte to 0x0, or the entire EEPROM?
Should I erase it first whenever I want to write a byte?

If not, why is there an option to erase and write separately?


How do I initiate an erase?

Either the datasheet is rather lacking concerning the EEPROM, or I'm just not finding what I'm looking for. I tried using a search engine, but all results are either about the Arduino EEPROM library or <avr/eeprom.h>, both of which use polling instead of interrupts (and are therefore blocking).

user62523: Your questions are answered in the AVR ATMega328 datasheet.
The procedure for erasing and writing the internal EEPROM is outlined in chapter 7.6 (Register Description).

The Erase operation erases 1 byte (erasing an EEPROM cell sets it to all 1s, i.e. 0xff).
The EEPROM address to be erased/programmed is pointed to by the EEARL and EEARH registers. The value to be programmed into that address is set by the EEDR. Reading a value from EEPROM returns the value in the same EEDR register.
Before writing a new value to the EEPROM, the old value must first be erased. You can do that as two separate actions or one single action. You could also leave the cell deprogrammed (erased) by only erasing it and not programming it again.
You initiate an erase of the EEPROM address pointed to by EEARH/EEARL, by setting EEPM1 to 1, EEPM0 to 0 and setting EEPE to 1 to start the erase operation. Setting EEPM1 and EEPM0 both to 0 will erase and program a new byte in a single operation.

As for making EEPROM writes non-blocking, you could set a (non-blocking) timer for the duration of the write, erase or erase/write operation. According to the datasheet these operations respectively take 1.8, 1.8 and 3.4 ms. Just make sure your code does not access the EEPROM while these operations are taking place.
You could also (non-blocking) periodically poll the EEPE bit until it is cleared, signalling the operation is finished.
The most elegant way, i.m.o. is to make use of the EERIE flag by setting it to 1, which will enable the ATmega to generate an interrupt when the EEPROM operation is finished.

80641: <p>The datasheet for the ATmega328P contains this table, which describes bits 4 and 5 of EECR:</p>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>EEPM1</th>
<th>EEPM0</th>
<th>Programming Time</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>0</td>
<td>3.4ms</td>
<td>Erase and write in one operation (atomic operation)</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>1.8ms</td>
<td>Erase only</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1.8ms</td>
<td>Write only</td>
</tr>
</tbody>
</table>
</div>
<p>I'm currently working on some non-blocking EEPROM-handling code and I'm wondering when and how I should erase the EEPROM.</p>
<ul>
<li>What does erasing do? Does it set one byte to 0x0, or the entire EEPROM?</li>
<li>Should I erase it first whenever I want to write a byte?
<ul>
<li>If not, why is there an option to erase and write separately?</li>
</ul>
</li>
<li>How do I initiate an erase?</li>
</ul>
<p>Either the datasheet is rather lacking concerning the EEPROM, or I'm just not finding what I'm looking for. I tried using a search engine, but all results are either about the Arduino EEPROM library or &lt;avr/eeprom.h&gt;, both of which use polling instead of interrupts (and are therefore blocking).</p>
 62523: <p>Your questions are answered in <a href="https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf" rel="nofollow noreferrer">the AVR ATMega328 datasheet</a>.</p>
<p>The procedure for erasing and writing the internal EEPROM is outlined in chapter 7.6 (Register Description).</p>
<ul>
<li>The Erase operation erases 1 byte (erasing an EEPROM cell sets it to all 1s, i.e. 0xff).</li>
<li>The EEPROM address to be erased/programmed is pointed to by the EEARL and EEARH registers. The value to be programmed into that address is set by the EEDR. Reading a value from EEPROM returns the value in the same EEDR register.</li>
<li>Before writing a new value to the EEPROM, the old value must first be erased. You can do that as two separate actions or one single action. You could also leave the cell deprogrammed (erased) by only erasing it and not programming it again.</li>
<li>You initiate an erase of the EEPROM address pointed to by EEARH/EEARL, by setting EEPM1 to 1, EEPM0 to 0 and setting EEPE to 1 to start the erase operation. Setting EEPM1 and EEPM0 both to 0 will erase and program a new byte in a single operation.</li>
</ul>
<p>As for making EEPROM writes non-blocking, you could set a (non-blocking) timer for the duration of the write, erase or erase/write operation. According to the datasheet these operations respectively take 1.8, 1.8 and 3.4 ms. Just make sure your code does not access the EEPROM while these operations are taking place.</p>
<p>You could also (non-blocking) periodically poll the EEPE bit until it is cleared, signalling the operation is finished.</p>
<p>The most elegant way, i.m.o. is to make use of the EERIE flag by setting it to 1, which will enable the ATmega to generate an interrupt when the EEPROM operation is finished.</p>
